summaryrefslogtreecommitdiffstats
path: root/test/integration/targets/ansible-galaxy/runme.sh
blob: 7d966e29e427cc747af2a7baa0df12d1011cd9ee (plain)
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
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
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
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
#!/usr/bin/env bash

set -eux -o pipefail

galaxy_testdir="${OUTPUT_DIR}/galaxy-test-dir"
role_testdir="${OUTPUT_DIR}/role-test-dir"
# Prep the local git repos with role and make a tar archive so we can test
# different things
galaxy_local_test_role="test-role"
galaxy_local_test_role_dir="${OUTPUT_DIR}/galaxy-role-test-root"
galaxy_local_test_role_git_repo="${galaxy_local_test_role_dir}/${galaxy_local_test_role}"
galaxy_local_test_role_tar="${galaxy_local_test_role_dir}/${galaxy_local_test_role}.tar"
galaxy_webserver_root="${OUTPUT_DIR}/ansible-galaxy-webserver"

mkdir -p "${galaxy_local_test_role_dir}"
mkdir -p "${role_testdir}"
mkdir -p "${galaxy_webserver_root}"

ansible-playbook setup.yml "$@"

trap 'ansible-playbook ${ANSIBLE_PLAYBOOK_DIR}/cleanup.yml' EXIT

# Very simple version test
ansible-galaxy --version

# Need a relative custom roles path for testing various scenarios of -p
galaxy_relative_rolespath="my/custom/roles/path"

# Status message function (f_ to designate that it's a function)
f_ansible_galaxy_status()
{
    printf "\n\n\n### Testing ansible-galaxy: %s\n" "${@}"
}

# Use to initialize a repository. Must call the post function too.
f_ansible_galaxy_create_role_repo_pre()
{
    repo_name=$1
    repo_dir=$2

    pushd "${repo_dir}"
        ansible-galaxy init "${repo_name}"
        pushd "${repo_name}"
            git init .

            # Prep git, because it doesn't work inside a docker container without it
            git config user.email "tester@ansible.com"
            git config user.name "Ansible Tester"

    # f_ansible_galaxy_create_role_repo_post
}

# Call after f_ansible_galaxy_create_repo_pre.
f_ansible_galaxy_create_role_repo_post()
{
    repo_name=$1
    repo_tar=$2

    # f_ansible_galaxy_create_role_repo_pre

            git add .
            git commit -m "local testing ansible galaxy role"

            git archive \
                --format=tar \
                --prefix="${repo_name}/" \
                master > "${repo_tar}"
            # Configure basic (insecure) HTTPS-accessible repository
            galaxy_local_test_role_http_repo="${galaxy_webserver_root}/${galaxy_local_test_role}.git"
            if [[ ! -d "${galaxy_local_test_role_http_repo}" ]]; then
                git clone --bare "${galaxy_local_test_role_git_repo}" "${galaxy_local_test_role_http_repo}"
                pushd "${galaxy_local_test_role_http_repo}"
                    touch "git-daemon-export-ok"
                    git --bare update-server-info
                    mv "hooks/post-update.sample" "hooks/post-update"
                popd # ${galaxy_local_test_role_http_repo}
            fi
        popd # "${repo_name}"
    popd # "${repo_dir}"
}

f_ansible_galaxy_create_role_repo_pre "${galaxy_local_test_role}" "${galaxy_local_test_role_dir}"
f_ansible_galaxy_create_role_repo_post "${galaxy_local_test_role}" "${galaxy_local_test_role_tar}"

galaxy_local_parent_role="parent-role"
galaxy_local_parent_role_dir="${OUTPUT_DIR}/parent-role"
mkdir -p "${galaxy_local_parent_role_dir}"
galaxy_local_parent_role_git_repo="${galaxy_local_parent_role_dir}/${galaxy_local_parent_role}"
galaxy_local_parent_role_tar="${galaxy_local_parent_role_dir}/${galaxy_local_parent_role}.tar"

# Create parent-role repository
f_ansible_galaxy_create_role_repo_pre "${galaxy_local_parent_role}" "${galaxy_local_parent_role_dir}"

    cat <<EOF > meta/requirements.yml
- src: git+file:///${galaxy_local_test_role_git_repo}
EOF
f_ansible_galaxy_create_role_repo_post "${galaxy_local_parent_role}" "${galaxy_local_parent_role_tar}"

# Galaxy install test case
#
# Install local git repo
f_ansible_galaxy_status "install of local git repo"
mkdir -p "${galaxy_testdir}"
pushd "${galaxy_testdir}"

    # minimum verbosity is hardcoded to include calls to Galaxy
    ansible-galaxy install git+file:///"${galaxy_local_test_role_git_repo}" "$@" -vvvv 2>&1 | tee out.txt

    # Test no initial call is made to Galaxy
    grep out.txt -e "https://galaxy.ansible.com" && cat out.txt && exit 1

    # Test that the role was installed to the expected directory
    [[ -d "${HOME}/.ansible/roles/${galaxy_local_test_role}" ]]
popd # ${galaxy_testdir}
rm -fr "${galaxy_testdir}"
rm -fr "${HOME}/.ansible/roles/${galaxy_local_test_role}"

# Galaxy install test case
#
# Install local git repo and ensure that if a role_path is passed, it is in fact used
f_ansible_galaxy_status "install of local git repo with -p \$role_path"
mkdir -p "${galaxy_testdir}"
pushd "${galaxy_testdir}"
    mkdir -p "${galaxy_relative_rolespath}"

    ansible-galaxy install git+file:///"${galaxy_local_test_role_git_repo}" -p "${galaxy_relative_rolespath}" "$@"

    # Test that the role was installed to the expected directory
    [[ -d "${galaxy_relative_rolespath}/${galaxy_local_test_role}" ]]
popd # ${galaxy_testdir}
rm -fr "${galaxy_testdir}"

# Galaxy install test case - skipping cert verification
#
# Install from remote git repo and ensure that cert validation is skipped
#
# Protect against regression (GitHub Issue #41077)
#   https://github.com/ansible/ansible/issues/41077
f_ansible_galaxy_status "install of role from untrusted repository"
mkdir -p "${galaxy_testdir}"
pushd "${galaxy_testdir}"
    mkdir -p "${galaxy_relative_rolespath}"

    # Without --ignore-certs, installing a role from an untrusted repository should fail
    set +e
    ansible-galaxy install --verbose git+https://localhost:4443/"${galaxy_local_test_role}.git" -p "${galaxy_relative_rolespath}" "$@" 2>&1 | tee out.txt
    ansible_exit_code="$?"
    set -e
    cat out.txt

    if [[ "$ansible_exit_code" -ne 1 ]]; then echo "Exit code ($ansible_exit_code) is expected to be 1" && exit "$ansible_exit_code"; fi
    [[ $(grep -c 'ERROR' out.txt) -eq 1 ]]
    [[ ! -d "${galaxy_relative_rolespath}/${galaxy_local_test_role}" ]]

    ansible-galaxy install --verbose --ignore-certs git+https://localhost:4443/"${galaxy_local_test_role}.git" -p "${galaxy_relative_rolespath}" "$@"

    # Test that the role was installed to the expected directory
    [[ -d "${galaxy_relative_rolespath}/${galaxy_local_test_role}" ]]
popd # ${galaxy_testdir}
rm -fr "${galaxy_testdir}"

# Galaxy install test case
#
# Install local git repo with a meta/requirements.yml
f_ansible_galaxy_status "install of local git repo with meta/requirements.yml"
mkdir -p "${galaxy_testdir}"
pushd "${galaxy_testdir}"

    ansible-galaxy install git+file:///"${galaxy_local_parent_role_git_repo}" "$@"

    # Test that the role was installed to the expected directory
    [[ -d "${HOME}/.ansible/roles/${galaxy_local_parent_role}" ]]

    # Test that the dependency was also installed
    [[ -d "${HOME}/.ansible/roles/${galaxy_local_test_role}" ]]

popd # ${galaxy_testdir}
rm -fr "${galaxy_testdir}"
rm -fr "${HOME}/.ansible/roles/${galaxy_local_parent_role}"
rm -fr "${HOME}/.ansible/roles/${galaxy_local_test_role}"

# Galaxy install test case
#
# Install local git repo with a meta/requirements.yml + --no-deps argument
f_ansible_galaxy_status "install of local git repo with meta/requirements.yml + --no-deps argument"
mkdir -p "${galaxy_testdir}"
pushd "${galaxy_testdir}"

    ansible-galaxy install git+file:///"${galaxy_local_parent_role_git_repo}" --no-deps "$@"

    # Test that the role was installed to the expected directory
    [[ -d "${HOME}/.ansible/roles/${galaxy_local_parent_role}" ]]

    # Test that the dependency was not installed
    [[ ! -d "${HOME}/.ansible/roles/${galaxy_local_test_role}" ]]

popd # ${galaxy_testdir}
rm -fr "${galaxy_testdir}"
rm -fr "${HOME}/.ansible/roles/${galaxy_local_test_role}"

# Galaxy install test case (expected failure)
#
# Install role with a meta/requirements.yml that is not a list of roles
mkdir -p "${role_testdir}"
pushd "${role_testdir}"

    ansible-galaxy role init --init-path . unsupported_requirements_format
    cat <<EOF > ./unsupported_requirements_format/meta/requirements.yml
roles:
  - src: git+file:///${galaxy_local_test_role_git_repo}
EOF
    tar czvf unsupported_requirements_format.tar.gz unsupported_requirements_format

    set +e
    ansible-galaxy role install -p ./roles unsupported_requirements_format.tar.gz 2>&1 | tee out.txt
    rc="$?"
    set -e

    # Test that installing the role was an error
    [[ ! "$rc" == 0 ]]
    grep out.txt -qe 'Expected role dependencies to be a list.'

    # Test that the role was not installed to the expected directory
    [[ ! -d "${HOME}/.ansible/roles/unsupported_requirements_format" ]]

popd # ${role_testdir}
rm -rf "${role_testdir}"

# Galaxy install test case (expected failure)
#
# Install role with meta/main.yml dependencies that is not a list of roles
mkdir -p "${role_testdir}"
pushd "${role_testdir}"

    ansible-galaxy role init --init-path . unsupported_requirements_format
    cat <<EOF > ./unsupported_requirements_format/meta/main.yml
galaxy_info:
  author: Ansible
  description: test unknown dependency format (expected failure)
  company: your company (optional)
  license: license (GPL-2.0-or-later, MIT, etc)
  min_ansible_version: 2.1
  galaxy_tags: []
dependencies:
  roles:
    - src: git+file:///${galaxy_local_test_role_git_repo}
EOF
    tar czvf unsupported_requirements_format.tar.gz unsupported_requirements_format

    set +e
    ansible-galaxy role install -p ./roles unsupported_requirements_format.tar.gz 2>&1 | tee out.txt
    rc="$?"
    set -e

    # Test that installing the role was an error
    [[ ! "$rc" == 0 ]]
    grep out.txt -qe 'Expected role dependencies to be a list.'

    # Test that the role was not installed to the expected directory
    [[ ! -d "${HOME}/.ansible/roles/unsupported_requirements_format" ]]

popd # ${role_testdir}
rm -rf "${role_testdir}"

# Galaxy install test case
#
# Ensure that if both a role_file and role_path is provided, they are both
# honored
#
# Protect against regression (GitHub Issue #35217)
#   https://github.com/ansible/ansible/issues/35217

f_ansible_galaxy_status \
    "install of local git repo and local tarball with -p \$role_path and -r \$role_file" \
    "Protect against regression (Issue #35217)"
mkdir -p "${galaxy_testdir}"
pushd "${galaxy_testdir}"

    git clone "${galaxy_local_test_role_git_repo}" "${galaxy_local_test_role}"
    ansible-galaxy init roles-path-bug "$@"
    pushd roles-path-bug
        cat <<EOF > ansible.cfg
[defaults]
roles_path = ../:../../:../roles:roles/
EOF
        cat <<EOF > requirements.yml
---
- src: ${galaxy_local_test_role_tar}
  name: ${galaxy_local_test_role}
EOF

        ansible-galaxy install -r requirements.yml -p roles/ "$@"
    popd # roles-path-bug

    # Test that the role was installed to the expected directory
    [[ -d "${galaxy_testdir}/roles-path-bug/roles/${galaxy_local_test_role}" ]]

popd # ${galaxy_testdir}
rm -fr "${galaxy_testdir}"


# Galaxy role list tests
#
# Basic tests to ensure listing roles works

f_ansible_galaxy_status "role list"
mkdir -p "${galaxy_testdir}"
pushd "${galaxy_testdir}"
    ansible-galaxy install git+file:///"${galaxy_local_test_role_git_repo}" "$@"

    ansible-galaxy role list | tee out.txt
    ansible-galaxy role list test-role | tee -a out.txt

    [[ $(grep -c '^- test-role' out.txt ) -eq 2 ]]
popd # ${galaxy_testdir}

# Galaxy role test case
#
# Test listing a specific role that is not in the first path in ANSIBLE_ROLES_PATH.
# https://github.com/ansible/ansible/issues/60167#issuecomment-585460706

f_ansible_galaxy_status \
    "list specific role not in the first path in ANSIBLE_ROLES_PATH"

mkdir -p "${role_testdir}"
pushd "${role_testdir}"

    mkdir testroles
    ansible-galaxy role init --init-path ./local-roles quark
    ANSIBLE_ROLES_PATH=./local-roles:${HOME}/.ansible/roles ansible-galaxy role list quark | tee out.txt

    [[ $(grep -c 'not found' out.txt) -eq 0 ]]

    ANSIBLE_ROLES_PATH=${HOME}/.ansible/roles:./local-roles ansible-galaxy role list quark | tee out.txt

    [[ $(grep -c 'not found' out.txt) -eq 0 ]]

popd # ${role_testdir}
rm -fr "${role_testdir}"


# Galaxy role info tests

# Get info about role that is not installed

f_ansible_galaxy_status "role info"
mkdir -p "${galaxy_testdir}"
pushd "${galaxy_testdir}"
    ansible-galaxy role info samdoran.fish | tee out.txt

    [[ $(grep -c 'not found' out.txt ) -eq 0 ]]
    [[ $(grep -c 'Role:.*samdoran\.fish' out.txt ) -eq 1 ]]

popd # ${galaxy_testdir}

f_ansible_galaxy_status \
    "role info non-existant role"

mkdir -p "${role_testdir}"
pushd "${role_testdir}"

    ansible-galaxy role info notaroll | tee out.txt

    grep -- '- the role notaroll was not found' out.txt

f_ansible_galaxy_status \
    "role info description offline"

    mkdir testroles
    ansible-galaxy role init testdesc --init-path ./testroles

    # Only galaxy_info['description'] exists in file
    sed -i -e 's#[[:space:]]\{1,\}description:.*$#  description: Description in galaxy_info#' ./testroles/testdesc/meta/main.yml
    ansible-galaxy role info -p ./testroles --offline testdesc | tee out.txt
    grep 'description: Description in galaxy_info' out.txt

    # Both top level 'description' and galaxy_info['description'] exist in file
    # Use shell-fu instead of sed to prepend a line to a file because BSD
    # and macOS sed don't work the same as GNU sed.
    echo 'description: Top level' | \
        cat - ./testroles/testdesc/meta/main.yml > tmp.yml && \
        mv tmp.yml ./testroles/testdesc/meta/main.yml
    ansible-galaxy role info -p ./testroles --offline testdesc | tee out.txt
    grep 'description: Top level' out.txt

    # Only top level 'description' exists in file
    sed -i.bak '/^[[:space:]]\{1,\}description: Description in galaxy_info/d' ./testroles/testdesc/meta/main.yml
    ansible-galaxy role info -p ./testroles --offline testdesc | tee out.txt
    grep 'description: Top level' out.txt

    # test multiple role listing
    ansible-galaxy role init otherrole --init-path ./testroles
    ansible-galaxy role info -p ./testroles --offline testdesc otherrole | tee out.txt
    grep 'Role: testdesc' out.txt
    grep 'Role: otherrole' out.txt


popd # ${role_testdir}
rm -fr "${role_testdir}"

# Properly list roles when the role name is a subset of the path, or the role
# name is the same name as the parent directory of the role. Issue #67365
#
# ./parrot/parrot
# ./parrot/arr
# ./testing-roles/test

f_ansible_galaxy_status \
    "list roles where the role name is the same or a subset of the role path (#67365)"

mkdir -p "${role_testdir}"
pushd "${role_testdir}"

    mkdir parrot
    ansible-galaxy role init --init-path ./parrot parrot
    ansible-galaxy role init --init-path ./parrot parrot-ship
    ansible-galaxy role init --init-path ./parrot arr

    ansible-galaxy role list -p ./parrot | tee out.txt

    [[ $(grep -Ec '\- (parrot|arr)' out.txt) -eq 3 ]]
    ansible-galaxy role list test-role | tee -a out.txt

popd # ${role_testdir}
rm -rf "${role_testdir}"

f_ansible_galaxy_status \
    "Test role with non-ascii characters"

mkdir -p "${role_testdir}"
pushd "${role_testdir}"

    mkdir nonascii
    ansible-galaxy role init --init-path ./nonascii nonascii
    touch nonascii/ÅÑŚÌβŁÈ.txt
    tar czvf nonascii.tar.gz nonascii
    ansible-galaxy role install -p ./roles nonascii.tar.gz

popd # ${role_testdir}
rm -rf "${role_testdir}"

f_ansible_galaxy_status \
    "Test if git hidden directories are skipped while using role skeleton (#71977)"

role_testdir=$(mktemp -d)
pushd "${role_testdir}"

    ansible-galaxy role init sample-role-skeleton
    git init ./sample-role-skeleton
    ansible-galaxy role init --role-skeleton=sample-role-skeleton example

popd # ${role_testdir}
rm -rf "${role_testdir}"

#################################
# ansible-galaxy collection tests
#################################
# TODO: Move these to ansible-galaxy-collection

mkdir -p "${galaxy_testdir}"
pushd "${galaxy_testdir}"

## ansible-galaxy collection list tests

# Create more collections and put them in various places
f_ansible_galaxy_status \
    "setting up for collection list tests"

rm -rf ansible_test/* install/*

NAMES=(zoo museum airport)
for n in "${NAMES[@]}"; do
    ansible-galaxy collection init "ansible_test.$n"
    ansible-galaxy collection build "ansible_test/$n"
done

ansible-galaxy collection install ansible_test-zoo-1.0.0.tar.gz
ansible-galaxy collection install ansible_test-museum-1.0.0.tar.gz -p ./install
ansible-galaxy collection install ansible_test-airport-1.0.0.tar.gz -p ./local

# Change the collection version and install to another location
sed -i -e 's#^version:.*#version: 2.5.0#' ansible_test/zoo/galaxy.yml
ansible-galaxy collection build ansible_test/zoo
ansible-galaxy collection install ansible_test-zoo-2.5.0.tar.gz -p ./local

# Test listing a collection that contains a galaxy.yml
ansible-galaxy collection init "ansible_test.development"
mv ./ansible_test/development "${galaxy_testdir}/local/ansible_collections/ansible_test/"

export ANSIBLE_COLLECTIONS_PATH=~/.ansible/collections:${galaxy_testdir}/local

f_ansible_galaxy_status \
    "collection list all collections"

    ansible-galaxy collection list -p ./install | tee out.txt

    [[ $(grep -c ansible_test out.txt) -eq 5 ]]

f_ansible_galaxy_status \
    "collection list specific collection"

    ansible-galaxy collection list -p ./install ansible_test.airport | tee out.txt

    [[ $(grep -c 'ansible_test\.airport' out.txt) -eq 1 ]]

f_ansible_galaxy_status \
    "collection list specific collection which contains galaxy.yml"

    ansible-galaxy collection list -p ./install ansible_test.development 2>&1 | tee out.txt

    [[ $(grep -c 'ansible_test\.development' out.txt) -eq 1 ]]
    [[ $(grep -c 'WARNING' out.txt) -eq 0 ]]

f_ansible_galaxy_status \
    "collection list specific collection found in multiple places"

    ansible-galaxy collection list -p ./install ansible_test.zoo | tee out.txt

    [[ $(grep -c 'ansible_test\.zoo' out.txt) -eq 2 ]]

f_ansible_galaxy_status \
    "collection list all with duplicate paths"

    ansible-galaxy collection list -p ~/.ansible/collections | tee out.txt

    [[ $(grep -c '# /root/.ansible/collections/ansible_collections' out.txt) -eq 1 ]]

f_ansible_galaxy_status \
    "collection list invalid collection name"

    ansible-galaxy collection list -p ./install dirty.wraughten.name "$@" 2>&1 | tee out.txt || echo "expected failure"

    grep 'ERROR! Invalid collection name' out.txt

f_ansible_galaxy_status \
    "collection list path not found"

    ansible-galaxy collection list -p ./nope "$@" 2>&1 | tee out.txt || echo "expected failure"

    grep '\[WARNING\]: - the configured path' out.txt

f_ansible_galaxy_status \
    "collection list missing ansible_collections dir inside path"

    mkdir emptydir

    ansible-galaxy collection list -p ./emptydir "$@"

    rmdir emptydir

unset ANSIBLE_COLLECTIONS_PATH

f_ansible_galaxy_status \
    "collection list with collections installed from python package"

    mkdir -p test-site-packages
    ln -s "${galaxy_testdir}/local/ansible_collections" test-site-packages/ansible_collections
    ansible-galaxy collection list
    PYTHONPATH="./test-site-packages/:$PYTHONPATH" ansible-galaxy collection list | tee out.txt

    grep ".ansible/collections/ansible_collections" out.txt
    grep "test-site-packages/ansible_collections" out.txt

## end ansible-galaxy collection list


popd # ${galaxy_testdir}

rm -fr "${galaxy_testdir}"

rm -fr "${galaxy_local_test_role_dir}"