mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-04-30 10:26:52 +00:00
Compare commits
298 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b56539f17e | ||
|
|
167d4bae90 | ||
|
|
de85c11bd1 | ||
|
|
d0731b111c | ||
|
|
7cd96ef3b6 | ||
|
|
b7a44a593e | ||
|
|
c413963ecb | ||
|
|
4f7d44aa10 | ||
|
|
56055d4f1e | ||
|
|
3fa4a9c073 | ||
|
|
1552bae77b | ||
|
|
a9cad80a36 | ||
|
|
fc79283662 | ||
|
|
0d8ea31781 | ||
|
|
7ac14f964b | ||
|
|
95d725a3cc | ||
|
|
95de8bd39d | ||
|
|
ecbdaca971 | ||
|
|
54754f7e81 | ||
|
|
bd15741647 | ||
|
|
fa05ca3f63 | ||
|
|
29992f1fbf | ||
|
|
34ab07865f | ||
|
|
5fa1fc65ca | ||
|
|
c0bb56c454 | ||
|
|
332ba8166c | ||
|
|
725450e57a | ||
|
|
f4311e08aa | ||
|
|
9e7b067904 | ||
|
|
d29db3ecf9 | ||
|
|
4aba7d5b87 | ||
|
|
88d00c32db | ||
|
|
f1e1b46ce2 | ||
|
|
c4256d8674 | ||
|
|
0bfed46136 | ||
|
|
a04912dec0 | ||
|
|
7f92aa0854 | ||
|
|
a16164cb72 | ||
|
|
3960153f70 | ||
|
|
6d4760eb20 | ||
|
|
777a741d4d | ||
|
|
aaf42f3646 | ||
|
|
c167ac10e0 | ||
|
|
154d8a313c | ||
|
|
b76492687b | ||
|
|
a118bb8d05 | ||
|
|
d2b1df49c1 | ||
|
|
fb3085e78d | ||
|
|
ad163ed3af | ||
|
|
15257e9a64 | ||
|
|
c642ee9157 | ||
|
|
7e89bc6f61 | ||
|
|
9defd1aca1 | ||
|
|
ff1a8415bd | ||
|
|
961011891b | ||
|
|
6470d3defe | ||
|
|
32ac93fb16 | ||
|
|
1dfe7963cf | ||
|
|
a46fb7bcae | ||
|
|
70a8ca6ac3 | ||
|
|
17f598fdc2 | ||
|
|
bc13182e1d | ||
|
|
6cbd0c772e | ||
|
|
49314a42ef | ||
|
|
4953fda9a0 | ||
|
|
e03431d9f6 | ||
|
|
ab94b0ace0 | ||
|
|
bd8df8e94e | ||
|
|
9bb439632b | ||
|
|
9e780b9d5e | ||
|
|
60e0a660ce | ||
|
|
7664146c9b | ||
|
|
28c455d234 | ||
|
|
74d4561a33 | ||
|
|
a07db2f731 | ||
|
|
528602f1b9 | ||
|
|
b99586e26a | ||
|
|
999620c789 | ||
|
|
d5c24e67e8 | ||
|
|
b1d1391be5 | ||
|
|
02f0abfb36 | ||
|
|
659ef811a3 | ||
|
|
b86161886f | ||
|
|
e29d585412 | ||
|
|
703bb465c7 | ||
|
|
1d290c129f | ||
|
|
af913c9a6a | ||
|
|
028481c55e | ||
|
|
247da9890b | ||
|
|
73d573b915 | ||
|
|
d1a7423196 | ||
|
|
7ace59f505 | ||
|
|
bcf0060f10 | ||
|
|
07e35f7505 | ||
|
|
9279e4532d | ||
|
|
51bf08c690 | ||
|
|
87e31ae886 | ||
|
|
7713202d9b | ||
|
|
e669562a0f | ||
|
|
17e39e3744 | ||
|
|
c1a6feaf25 | ||
|
|
bdeb63e579 | ||
|
|
7e247b0eea | ||
|
|
2fe6a34e3f | ||
|
|
ca97eb6f93 | ||
|
|
b529955c07 | ||
|
|
d5d24302b6 | ||
|
|
51a3594494 | ||
|
|
85fd4240f6 | ||
|
|
490495937b | ||
|
|
0e7a130ec3 | ||
|
|
5239357077 | ||
|
|
8cd126be26 | ||
|
|
d2e259da4a | ||
|
|
6bd10adb97 | ||
|
|
71b63e6a75 | ||
|
|
1ce00126c5 | ||
|
|
011e27caf5 | ||
|
|
726ea65f4f | ||
|
|
85307d28e2 | ||
|
|
f6fe843a57 | ||
|
|
ee04231964 | ||
|
|
e09392e867 | ||
|
|
1b7c49cf56 | ||
|
|
e5cddcaf87 | ||
|
|
82162b35c4 | ||
|
|
2233c94a6f | ||
|
|
eba42c9eb9 | ||
|
|
dbb145bc71 | ||
|
|
373df2ba68 | ||
|
|
4cd7476604 | ||
|
|
24f973a9d1 | ||
|
|
f1ca1ccd89 | ||
|
|
0564a2239f | ||
|
|
a3a33cb019 | ||
|
|
399c28c11e | ||
|
|
18da4d22f8 | ||
|
|
d4435b0b8d | ||
|
|
c4983f9b90 | ||
|
|
0005df8910 | ||
|
|
130709348d | ||
|
|
901bca58bb | ||
|
|
5a826a5cb7 | ||
|
|
924f18535a | ||
|
|
be27bf1eae | ||
|
|
29819e04ec | ||
|
|
bf9a6c08d0 | ||
|
|
6708ee1afd | ||
|
|
88bd8fc7ea | ||
|
|
5d0a0d27e5 | ||
|
|
d74680a3c6 | ||
|
|
19a7aa462b | ||
|
|
176c9a90ca | ||
|
|
c4e93b0b5f | ||
|
|
08831e193f | ||
|
|
6ea7616541 | ||
|
|
34c164dc78 | ||
|
|
2ff06d2fdf | ||
|
|
3a69dd949d | ||
|
|
82c79e9a06 | ||
|
|
96a970475f | ||
|
|
f3e07723cd | ||
|
|
9f93219611 | ||
|
|
922dd0fc10 | ||
|
|
a3a0c5c3fd | ||
|
|
a20e221d6f | ||
|
|
d0a9ced474 | ||
|
|
b035084caa | ||
|
|
b56857932e | ||
|
|
7da1f3ffea | ||
|
|
c826a81b40 | ||
|
|
af4f1f727d | ||
|
|
5571a0cdf8 | ||
|
|
bb2ad10eef | ||
|
|
788dc4bc23 | ||
|
|
705118247d | ||
|
|
1b579dfdc2 | ||
|
|
e3e3682eb3 | ||
|
|
3c6e84b21c | ||
|
|
28ec0b07e9 | ||
|
|
22e0fa03b2 | ||
|
|
b3cac071fa | ||
|
|
ebb9d8a6fa | ||
|
|
f8fcc827cd | ||
|
|
f9ac30a531 | ||
|
|
efa884b64a | ||
|
|
ee8f87412a | ||
|
|
2cb3cec659 | ||
|
|
6092cd89bc | ||
|
|
dd47c3a548 | ||
|
|
06678d4ce3 | ||
|
|
ba10525125 | ||
|
|
713e386c66 | ||
|
|
adf61bf7f4 | ||
|
|
97507b50b5 | ||
|
|
c0971e41b0 | ||
|
|
0b28f5d9e4 | ||
|
|
7c0175322b | ||
|
|
4e497ace29 | ||
|
|
26bb835975 | ||
|
|
5d3a2a3bd4 | ||
|
|
686cdf2a6b | ||
|
|
4928810dda | ||
|
|
4dc2e14039 | ||
|
|
6ec769b051 | ||
|
|
e4d3d24b26 | ||
|
|
572e3f0814 | ||
|
|
e03ade818a | ||
|
|
54725bea77 | ||
|
|
db24f9857a | ||
|
|
c00147e532 | ||
|
|
0baceda7f6 | ||
|
|
c563813e4e | ||
|
|
1dbd7d4d00 | ||
|
|
41b72c0055 | ||
|
|
96a8390b5e | ||
|
|
25474f657a | ||
|
|
d7c4849473 | ||
|
|
0d459e5662 | ||
|
|
01bbab6b2c | ||
|
|
59a7064392 | ||
|
|
8e7b779ec9 | ||
|
|
1ba5344258 | ||
|
|
58e9454379 | ||
|
|
af3dec9b97 | ||
|
|
99a161bd06 | ||
|
|
feabad39f4 | ||
|
|
4a5276b589 | ||
|
|
e342dfb467 | ||
|
|
5b425fc297 | ||
|
|
d8328312a1 | ||
|
|
2ce326ca5b | ||
|
|
90ed2fa5c3 | ||
|
|
407d776610 | ||
|
|
951806c888 | ||
|
|
0fe7ea63a8 | ||
|
|
3a95a84963 | ||
|
|
2c3e93cc4d | ||
|
|
656b25a4a1 | ||
|
|
1863694297 | ||
|
|
c0f753dd21 | ||
|
|
369cde2320 | ||
|
|
e90872b486 | ||
|
|
b52d3504cb | ||
|
|
1e150cda01 | ||
|
|
db135b83dc | ||
|
|
ad4866bb3b | ||
|
|
83339c44b3 | ||
|
|
71633249c4 | ||
|
|
fdf244d488 | ||
|
|
5575d454ab | ||
|
|
d4633cfcd5 | ||
|
|
11315c8c69 | ||
|
|
6c387f87dd | ||
|
|
33cf4877f5 | ||
|
|
6e2fee77a7 | ||
|
|
502e5ceb79 | ||
|
|
4685a53f29 | ||
|
|
79616f47cb | ||
|
|
496218b6e6 | ||
|
|
8bd8ccd974 | ||
|
|
c802de865a | ||
|
|
1dfd6e395c | ||
|
|
25eabb39a6 | ||
|
|
869e0e60c2 | ||
|
|
cae5823685 | ||
|
|
3d0dbc1fb0 | ||
|
|
912583026f | ||
|
|
748304dadd | ||
|
|
253c2179de | ||
|
|
fcc72e5af1 | ||
|
|
d472953e10 | ||
|
|
c78d6c95d6 | ||
|
|
c9cb987eb7 | ||
|
|
099a99d288 | ||
|
|
26ea01d5b4 | ||
|
|
a9afbe59e5 | ||
|
|
dc9cab36ac | ||
|
|
99265c5126 | ||
|
|
57aede6b95 | ||
|
|
e51e41203a | ||
|
|
54644179ea | ||
|
|
7d6a1a4483 | ||
|
|
2715e4456c | ||
|
|
a335d1cc56 | ||
|
|
a89b43b110 | ||
|
|
1b599bde37 | ||
|
|
7bd987e2b9 | ||
|
|
8b0896a43d | ||
|
|
402bb01501 | ||
|
|
75afd83508 | ||
|
|
b25f0f3cd2 | ||
|
|
9226c4b0d5 | ||
|
|
fe3e262209 | ||
|
|
b9fac26dcd | ||
|
|
343e5a03a7 | ||
|
|
acea082a7c | ||
|
|
0cff1f116f |
@@ -13,25 +13,13 @@ pr:
|
|||||||
- stable-*
|
- stable-*
|
||||||
|
|
||||||
schedules:
|
schedules:
|
||||||
- cron: 0 8 * * *
|
- cron: 0 9 * * *
|
||||||
displayName: Nightly (main)
|
displayName: Nightly
|
||||||
always: true
|
always: true
|
||||||
branches:
|
branches:
|
||||||
include:
|
include:
|
||||||
- main
|
- main
|
||||||
- cron: 0 10 * * *
|
- stable-*
|
||||||
displayName: Nightly (active stable branches)
|
|
||||||
always: true
|
|
||||||
branches:
|
|
||||||
include:
|
|
||||||
- stable-2
|
|
||||||
- stable-3
|
|
||||||
- cron: 0 11 * * 0
|
|
||||||
displayName: Weekly (old stable branches)
|
|
||||||
always: true
|
|
||||||
branches:
|
|
||||||
include:
|
|
||||||
- stable-1
|
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
- name: checkoutPath
|
- name: checkoutPath
|
||||||
@@ -48,39 +36,26 @@ variables:
|
|||||||
resources:
|
resources:
|
||||||
containers:
|
containers:
|
||||||
- container: default
|
- container: default
|
||||||
image: quay.io/ansible/azure-pipelines-test-container:1.9.0
|
image: quay.io/ansible/azure-pipelines-test-container:1.7.1
|
||||||
|
|
||||||
pool: Standard
|
pool: Standard
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
### Sanity
|
### Sanity
|
||||||
- stage: Sanity_2_12
|
- stage: Sanity_devel
|
||||||
displayName: Sanity 2.12
|
displayName: Sanity devel
|
||||||
dependsOn: []
|
dependsOn: []
|
||||||
jobs:
|
jobs:
|
||||||
- template: templates/matrix.yml
|
- template: templates/matrix.yml
|
||||||
parameters:
|
parameters:
|
||||||
nameFormat: Test {0}
|
nameFormat: Test {0}
|
||||||
testFormat: 2.12/sanity/{0}
|
testFormat: devel/sanity/{0}
|
||||||
targets:
|
targets:
|
||||||
- test: 1
|
- test: 1
|
||||||
- test: 2
|
- test: 2
|
||||||
- test: 3
|
- test: 3
|
||||||
- test: 4
|
- test: 4
|
||||||
- test: extra
|
- test: extra
|
||||||
- stage: Sanity_2_11
|
|
||||||
displayName: Sanity 2.11
|
|
||||||
dependsOn: []
|
|
||||||
jobs:
|
|
||||||
- template: templates/matrix.yml
|
|
||||||
parameters:
|
|
||||||
nameFormat: Test {0}
|
|
||||||
testFormat: 2.11/sanity/{0}
|
|
||||||
targets:
|
|
||||||
- test: 1
|
|
||||||
- test: 2
|
|
||||||
- test: 3
|
|
||||||
- test: 4
|
|
||||||
- stage: Sanity_2_10
|
- stage: Sanity_2_10
|
||||||
displayName: Sanity 2.10
|
displayName: Sanity 2.10
|
||||||
dependsOn: []
|
dependsOn: []
|
||||||
@@ -108,31 +83,14 @@ stages:
|
|||||||
- test: 3
|
- test: 3
|
||||||
- test: 4
|
- test: 4
|
||||||
### Units
|
### Units
|
||||||
- stage: Units_2_12
|
- stage: Units_devel
|
||||||
displayName: Units 2.12
|
displayName: Units devel
|
||||||
dependsOn: []
|
dependsOn: []
|
||||||
jobs:
|
jobs:
|
||||||
- template: templates/matrix.yml
|
- template: templates/matrix.yml
|
||||||
parameters:
|
parameters:
|
||||||
nameFormat: Python {0}
|
nameFormat: Python {0}
|
||||||
testFormat: 2.12/units/{0}/1
|
testFormat: devel/units/{0}/1
|
||||||
targets:
|
|
||||||
- test: 2.6
|
|
||||||
- test: 2.7
|
|
||||||
- test: 3.5
|
|
||||||
- test: 3.6
|
|
||||||
- test: 3.7
|
|
||||||
- test: 3.8
|
|
||||||
- test: 3.9
|
|
||||||
- test: '3.10'
|
|
||||||
- stage: Units_2_11
|
|
||||||
displayName: Units 2.11
|
|
||||||
dependsOn: []
|
|
||||||
jobs:
|
|
||||||
- template: templates/matrix.yml
|
|
||||||
parameters:
|
|
||||||
nameFormat: Python {0}
|
|
||||||
testFormat: 2.11/units/{0}/1
|
|
||||||
targets:
|
targets:
|
||||||
- test: 2.6
|
- test: 2.6
|
||||||
- test: 2.7
|
- test: 2.7
|
||||||
@@ -174,47 +132,32 @@ stages:
|
|||||||
- test: 3.8
|
- test: 3.8
|
||||||
|
|
||||||
## Remote
|
## Remote
|
||||||
- stage: Remote_2_12
|
- stage: Remote_devel
|
||||||
displayName: Remote 2.12
|
displayName: Remote devel
|
||||||
dependsOn: []
|
dependsOn: []
|
||||||
jobs:
|
jobs:
|
||||||
- template: templates/matrix.yml
|
- template: templates/matrix.yml
|
||||||
parameters:
|
parameters:
|
||||||
testFormat: 2.12/{0}
|
testFormat: devel/{0}
|
||||||
targets:
|
targets:
|
||||||
- name: macOS 11.1
|
- name: OS X 10.11
|
||||||
test: macos/11.1
|
test: osx/10.11
|
||||||
- name: RHEL 7.9
|
- name: macOS 10.15
|
||||||
test: rhel/7.9
|
test: macos/10.15
|
||||||
- name: RHEL 8.4
|
- name: RHEL 7.8
|
||||||
test: rhel/8.4
|
test: rhel/7.8
|
||||||
- name: FreeBSD 12.2
|
- name: RHEL 8.2
|
||||||
test: freebsd/12.2
|
test: rhel/8.2
|
||||||
- name: FreeBSD 13.0
|
- name: FreeBSD 11.1
|
||||||
test: freebsd/13.0
|
test: freebsd/11.1
|
||||||
|
- name: FreeBSD 12.1
|
||||||
|
test: freebsd/12.1
|
||||||
groups:
|
groups:
|
||||||
- 1
|
- 1
|
||||||
- 2
|
- 2
|
||||||
- 3
|
- 3
|
||||||
- stage: Remote_2_11
|
- 4
|
||||||
displayName: Remote 2.11
|
- 5
|
||||||
dependsOn: []
|
|
||||||
jobs:
|
|
||||||
- template: templates/matrix.yml
|
|
||||||
parameters:
|
|
||||||
testFormat: 2.11/{0}
|
|
||||||
targets:
|
|
||||||
- name: macOS 11.1
|
|
||||||
test: macos/11.1
|
|
||||||
- name: RHEL 7.9
|
|
||||||
test: rhel/7.9
|
|
||||||
- name: RHEL 8.3
|
|
||||||
test: rhel/8.3
|
|
||||||
- name: FreeBSD 12.2
|
|
||||||
test: freebsd/12.2
|
|
||||||
groups:
|
|
||||||
- 1
|
|
||||||
- 2
|
|
||||||
- stage: Remote_2_10
|
- stage: Remote_2_10
|
||||||
displayName: Remote 2.10
|
displayName: Remote 2.10
|
||||||
dependsOn: []
|
dependsOn: []
|
||||||
@@ -225,12 +168,6 @@ stages:
|
|||||||
targets:
|
targets:
|
||||||
- name: OS X 10.11
|
- name: OS X 10.11
|
||||||
test: osx/10.11
|
test: osx/10.11
|
||||||
- name: macOS 10.15
|
|
||||||
test: macos/10.15
|
|
||||||
- name: macOS 11.1
|
|
||||||
test: macos/11.1
|
|
||||||
- name: RHEL 7.8
|
|
||||||
test: rhel/7.8
|
|
||||||
- name: RHEL 8.2
|
- name: RHEL 8.2
|
||||||
test: rhel/8.2
|
test: rhel/8.2
|
||||||
- name: FreeBSD 12.1
|
- name: FreeBSD 12.1
|
||||||
@@ -238,6 +175,9 @@ stages:
|
|||||||
groups:
|
groups:
|
||||||
- 1
|
- 1
|
||||||
- 2
|
- 2
|
||||||
|
- 3
|
||||||
|
- 4
|
||||||
|
- 5
|
||||||
- stage: Remote_2_9
|
- stage: Remote_2_9
|
||||||
displayName: Remote 2.9
|
displayName: Remote 2.9
|
||||||
dependsOn: []
|
dependsOn: []
|
||||||
@@ -248,20 +188,23 @@ stages:
|
|||||||
targets:
|
targets:
|
||||||
- name: RHEL 8.2
|
- name: RHEL 8.2
|
||||||
test: rhel/8.2
|
test: rhel/8.2
|
||||||
- name: FreeBSD 12.0
|
#- name: FreeBSD 12.0
|
||||||
test: freebsd/12.0
|
# test: freebsd/12.0
|
||||||
groups:
|
groups:
|
||||||
- 1
|
- 1
|
||||||
- 2
|
- 2
|
||||||
|
- 3
|
||||||
|
- 4
|
||||||
|
- 5
|
||||||
|
|
||||||
### Docker
|
### Docker
|
||||||
- stage: Docker_2_12
|
- stage: Docker_devel
|
||||||
displayName: Docker 2.12
|
displayName: Docker devel
|
||||||
dependsOn: []
|
dependsOn: []
|
||||||
jobs:
|
jobs:
|
||||||
- template: templates/matrix.yml
|
- template: templates/matrix.yml
|
||||||
parameters:
|
parameters:
|
||||||
testFormat: 2.12/linux/{0}
|
testFormat: devel/linux/{0}
|
||||||
targets:
|
targets:
|
||||||
- name: CentOS 6
|
- name: CentOS 6
|
||||||
test: centos6
|
test: centos6
|
||||||
@@ -269,41 +212,24 @@ stages:
|
|||||||
test: centos7
|
test: centos7
|
||||||
- name: CentOS 8
|
- name: CentOS 8
|
||||||
test: centos8
|
test: centos8
|
||||||
- name: Fedora 33
|
- name: Fedora 31
|
||||||
test: fedora33
|
test: fedora31
|
||||||
- name: Fedora 34
|
- name: Fedora 32
|
||||||
test: fedora34
|
test: fedora32
|
||||||
- name: openSUSE 15 py2
|
- name: openSUSE 15 py2
|
||||||
test: opensuse15py2
|
test: opensuse15py2
|
||||||
- name: openSUSE 15 py3
|
- name: openSUSE 15 py3
|
||||||
test: opensuse15
|
test: opensuse15
|
||||||
|
- name: Ubuntu 16.04
|
||||||
|
test: ubuntu1604
|
||||||
- name: Ubuntu 18.04
|
- name: Ubuntu 18.04
|
||||||
test: ubuntu1804
|
test: ubuntu1804
|
||||||
- name: Ubuntu 20.04
|
|
||||||
test: ubuntu2004
|
|
||||||
groups:
|
groups:
|
||||||
- 1
|
- 1
|
||||||
- 2
|
- 2
|
||||||
- 3
|
- 3
|
||||||
- stage: Docker_2_11
|
- 4
|
||||||
displayName: Docker 2.11
|
- 5
|
||||||
dependsOn: []
|
|
||||||
jobs:
|
|
||||||
- template: templates/matrix.yml
|
|
||||||
parameters:
|
|
||||||
testFormat: 2.11/linux/{0}
|
|
||||||
targets:
|
|
||||||
- name: CentOS 8
|
|
||||||
test: centos8
|
|
||||||
- name: Fedora 33
|
|
||||||
test: fedora33
|
|
||||||
- name: openSUSE 15 py3
|
|
||||||
test: opensuse15
|
|
||||||
- name: Ubuntu 20.04
|
|
||||||
test: ubuntu2004
|
|
||||||
groups:
|
|
||||||
- 2
|
|
||||||
- 3
|
|
||||||
- stage: Docker_2_10
|
- stage: Docker_2_10
|
||||||
displayName: Docker 2.10
|
displayName: Docker 2.10
|
||||||
dependsOn: []
|
dependsOn: []
|
||||||
@@ -312,17 +238,20 @@ stages:
|
|||||||
parameters:
|
parameters:
|
||||||
testFormat: 2.10/linux/{0}
|
testFormat: 2.10/linux/{0}
|
||||||
targets:
|
targets:
|
||||||
- name: CentOS 8
|
#- name: CentOS 8
|
||||||
test: centos8
|
# test: centos8
|
||||||
- name: Fedora 32
|
- name: Fedora 32
|
||||||
test: fedora32
|
test: fedora32
|
||||||
- name: openSUSE 15 py3
|
- name: openSUSE 15 py3
|
||||||
test: opensuse15
|
test: opensuse15
|
||||||
- name: Ubuntu 16.04
|
- name: Ubuntu 18.04
|
||||||
test: ubuntu1604
|
test: ubuntu1804
|
||||||
groups:
|
groups:
|
||||||
|
- 1
|
||||||
- 2
|
- 2
|
||||||
- 3
|
- 3
|
||||||
|
- 4
|
||||||
|
- 5
|
||||||
- stage: Docker_2_9
|
- stage: Docker_2_9
|
||||||
displayName: Docker 2.9
|
displayName: Docker 2.9
|
||||||
dependsOn: []
|
dependsOn: []
|
||||||
@@ -331,35 +260,30 @@ stages:
|
|||||||
parameters:
|
parameters:
|
||||||
testFormat: 2.9/linux/{0}
|
testFormat: 2.9/linux/{0}
|
||||||
targets:
|
targets:
|
||||||
- name: CentOS 8
|
#- name: CentOS 8
|
||||||
test: centos8
|
# test: centos8
|
||||||
- name: Fedora 31
|
#- name: Fedora 31
|
||||||
test: fedora31
|
# test: fedora31
|
||||||
- name: openSUSE 15 py3
|
#- name: openSUSE 15 py3
|
||||||
test: opensuse15
|
# test: opensuse15
|
||||||
|
- name: Ubuntu 18.04
|
||||||
|
test: ubuntu1804
|
||||||
groups:
|
groups:
|
||||||
|
- 1
|
||||||
- 2
|
- 2
|
||||||
- 3
|
- 3
|
||||||
|
- 4
|
||||||
|
- 5
|
||||||
|
|
||||||
### Cloud
|
### Cloud
|
||||||
- stage: Cloud_2_12
|
- stage: Cloud_devel
|
||||||
displayName: Cloud 2.12
|
displayName: Cloud devel
|
||||||
dependsOn: []
|
dependsOn: []
|
||||||
jobs:
|
jobs:
|
||||||
- template: templates/matrix.yml
|
- template: templates/matrix.yml
|
||||||
parameters:
|
parameters:
|
||||||
nameFormat: Python {0}
|
nameFormat: Python {0}
|
||||||
testFormat: 2.12/cloud/{0}/1
|
testFormat: devel/cloud/{0}/1
|
||||||
targets:
|
|
||||||
- test: 3.8
|
|
||||||
- stage: Cloud_2_11
|
|
||||||
displayName: Cloud 2.11
|
|
||||||
dependsOn: []
|
|
||||||
jobs:
|
|
||||||
- template: templates/matrix.yml
|
|
||||||
parameters:
|
|
||||||
nameFormat: Python {0}
|
|
||||||
testFormat: 2.11/cloud/{0}/1
|
|
||||||
targets:
|
targets:
|
||||||
- test: 2.7
|
- test: 2.7
|
||||||
- test: 3.6
|
- test: 3.6
|
||||||
@@ -382,29 +306,24 @@ stages:
|
|||||||
nameFormat: Python {0}
|
nameFormat: Python {0}
|
||||||
testFormat: 2.9/cloud/{0}/1
|
testFormat: 2.9/cloud/{0}/1
|
||||||
targets:
|
targets:
|
||||||
- test: 3.6
|
- test: 2.7
|
||||||
- stage: Summary
|
- stage: Summary
|
||||||
condition: succeededOrFailed()
|
condition: succeededOrFailed()
|
||||||
dependsOn:
|
dependsOn:
|
||||||
- Sanity_2_12
|
- Sanity_devel
|
||||||
- Sanity_2_9
|
- Sanity_2_9
|
||||||
- Sanity_2_10
|
- Sanity_2_10
|
||||||
- Sanity_2_11
|
- Units_devel
|
||||||
- Units_2_12
|
|
||||||
- Units_2_9
|
- Units_2_9
|
||||||
- Units_2_10
|
- Units_2_10
|
||||||
- Units_2_11
|
- Remote_devel
|
||||||
- Remote_2_12
|
|
||||||
- Remote_2_9
|
- Remote_2_9
|
||||||
- Remote_2_10
|
- Remote_2_10
|
||||||
- Remote_2_11
|
- Docker_devel
|
||||||
- Docker_2_12
|
|
||||||
- Docker_2_9
|
- Docker_2_9
|
||||||
- Docker_2_10
|
- Docker_2_10
|
||||||
- Docker_2_11
|
- Cloud_devel
|
||||||
- Cloud_2_12
|
|
||||||
- Cloud_2_9
|
- Cloud_2_9
|
||||||
- Cloud_2_10
|
- Cloud_2_10
|
||||||
- Cloud_2_11
|
|
||||||
jobs:
|
jobs:
|
||||||
- template: templates/coverage.yml
|
- template: templates/coverage.yml
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ set -o pipefail -eu
|
|||||||
|
|
||||||
output_path="$1"
|
output_path="$1"
|
||||||
|
|
||||||
curl --silent --show-error https://ansible-ci-files.s3.us-east-1.amazonaws.com/codecov/codecov.sh > codecov.sh
|
curl --silent --show-error https://codecov.io/bash > codecov.sh
|
||||||
|
|
||||||
for file in "${output_path}"/reports/coverage*.xml; do
|
for file in "${output_path}"/reports/coverage*.xml; do
|
||||||
name="${file}"
|
name="${file}"
|
||||||
|
|||||||
222
.github/BOTMETA.yml
vendored
222
.github/BOTMETA.yml
vendored
@@ -1,29 +1,28 @@
|
|||||||
notifications: true
|
|
||||||
automerge: true
|
automerge: true
|
||||||
files:
|
files:
|
||||||
plugins/:
|
|
||||||
supershipit: quidame
|
|
||||||
changelogs/fragments/:
|
changelogs/fragments/:
|
||||||
support: community
|
support: community
|
||||||
$actions:
|
$actions:
|
||||||
labels: action
|
labels: action
|
||||||
$actions/system/iptables_state.py:
|
$actions/aireos.py:
|
||||||
maintainers: quidame
|
labels: aireos cisco networking
|
||||||
$actions/system/shutdown.py:
|
$actions/ironware.py:
|
||||||
|
maintainers: paulquack
|
||||||
|
labels: ironware networking
|
||||||
|
$actions/shutdown.py:
|
||||||
maintainers: nitzmahone samdoran aminvakil
|
maintainers: nitzmahone samdoran aminvakil
|
||||||
$becomes/:
|
$becomes/:
|
||||||
labels: become
|
labels: become
|
||||||
$callbacks/:
|
$callbacks/:
|
||||||
labels: callbacks
|
labels: callbacks
|
||||||
$callbacks/loganalytics.py:
|
|
||||||
maintainers: zhcli
|
|
||||||
$callbacks/logstash.py:
|
|
||||||
maintainers: ujenmr
|
|
||||||
$callbacks/say.py:
|
$callbacks/say.py:
|
||||||
notify: chris-short
|
notify: chris-short
|
||||||
maintainers: $team_macos
|
maintainers: $team_macos
|
||||||
labels: macos say
|
labels: macos say
|
||||||
keywords: brew cask darwin homebrew macosx macports osx
|
keywords: brew cask darwin homebrew macosx macports osx
|
||||||
|
$callbacks/stderr.py:
|
||||||
|
maintainers: ysn2233
|
||||||
|
labels: stderr
|
||||||
$callbacks/sumologic.py:
|
$callbacks/sumologic.py:
|
||||||
maintainers: ryancurrah
|
maintainers: ryancurrah
|
||||||
labels: sumologic
|
labels: sumologic
|
||||||
@@ -32,6 +31,11 @@ files:
|
|||||||
$callbacks/unixy.py:
|
$callbacks/unixy.py:
|
||||||
maintainers: akatch
|
maintainers: akatch
|
||||||
labels: unixy
|
labels: unixy
|
||||||
|
$connections/docker.py:
|
||||||
|
maintainers: $team_docker
|
||||||
|
labels: cloud docker
|
||||||
|
ignore: cove
|
||||||
|
supershipit: felixfontein
|
||||||
$connections/:
|
$connections/:
|
||||||
labels: connections
|
labels: connections
|
||||||
$connections/kubectl.py:
|
$connections/kubectl.py:
|
||||||
@@ -40,10 +44,24 @@ files:
|
|||||||
$connections/lxd.py:
|
$connections/lxd.py:
|
||||||
maintainers: mattclay
|
maintainers: mattclay
|
||||||
labels: lxd
|
labels: lxd
|
||||||
|
$connections/oc.py:
|
||||||
|
maintainers: chouseknecht fabianvf flaper87 maxamillion
|
||||||
|
labels: oc
|
||||||
$connections/saltstack.py:
|
$connections/saltstack.py:
|
||||||
labels: saltstack
|
labels: saltstack
|
||||||
$doc_fragments/:
|
$doc_fragments/:
|
||||||
labels: docs_fragments
|
labels: docs_fragments
|
||||||
|
$doc_fragments/docker.py:
|
||||||
|
maintainers: $team_docker
|
||||||
|
labels: cloud docker
|
||||||
|
ignore: cove
|
||||||
|
supershipit: felixfontein
|
||||||
|
$doc_fragments/gcp.py:
|
||||||
|
maintainers: $team_google
|
||||||
|
labels: gcp
|
||||||
|
supershipit: erjohnso rambleraptor
|
||||||
|
$doc_fragments/hetzner.py:
|
||||||
|
labels: hetzner
|
||||||
$doc_fragments/hpe3par.py:
|
$doc_fragments/hpe3par.py:
|
||||||
maintainers: farhan7500 gautamphegde
|
maintainers: farhan7500 gautamphegde
|
||||||
labels: hpe3par
|
labels: hpe3par
|
||||||
@@ -52,25 +70,19 @@ files:
|
|||||||
labels: hwc
|
labels: hwc
|
||||||
$doc_fragments/nomad.py:
|
$doc_fragments/nomad.py:
|
||||||
maintainers: chris93111
|
maintainers: chris93111
|
||||||
|
$doc_fragments/postgres.py:
|
||||||
|
maintainers: $team_postgresql
|
||||||
|
labels: postgres postgresql
|
||||||
|
keywords: database postgres postgresql
|
||||||
$doc_fragments/xenserver.py:
|
$doc_fragments/xenserver.py:
|
||||||
maintainers: bvitnik
|
maintainers: bvitnik
|
||||||
labels: xenserver
|
labels: xenserver
|
||||||
$filters/dict.py:
|
|
||||||
maintainers: felixfontein
|
|
||||||
$filters/dict_kv.py:
|
$filters/dict_kv.py:
|
||||||
maintainers: giner
|
maintainers: giner
|
||||||
$filters/from_csv.py:
|
|
||||||
maintainers: Ajpantuso
|
|
||||||
$filters/jc.py:
|
|
||||||
maintainers: kellyjonbrazil
|
|
||||||
$filters/list.py:
|
|
||||||
maintainers: vbotka
|
|
||||||
$filters/path_join_shim.py:
|
|
||||||
maintainers: felixfontein
|
|
||||||
$filters/time.py:
|
$filters/time.py:
|
||||||
maintainers: resmo
|
maintainers: resmo
|
||||||
$filters/version_sort.py:
|
$filters/jc.py:
|
||||||
maintainers: ericzolf
|
maintainers: kellyjonbrazil
|
||||||
$httpapis/:
|
$httpapis/:
|
||||||
maintainers: $team_networking
|
maintainers: $team_networking
|
||||||
labels: networking
|
labels: networking
|
||||||
@@ -80,12 +92,20 @@ files:
|
|||||||
keywords: firepower ftd
|
keywords: firepower ftd
|
||||||
$inventories/:
|
$inventories/:
|
||||||
labels: inventories
|
labels: inventories
|
||||||
|
$inventories/docker_machine.py:
|
||||||
|
maintainers: $team_docker
|
||||||
|
labels: cloud docker
|
||||||
|
ignore: cove
|
||||||
|
supershipit: felixfontein
|
||||||
|
$inventories/docker_swarm.py:
|
||||||
|
maintainers: $team_docker morph027
|
||||||
|
labels: cloud docker docker_swarm
|
||||||
|
ignore: cove
|
||||||
|
supershipit: felixfontein
|
||||||
$inventories/linode.py:
|
$inventories/linode.py:
|
||||||
maintainers: $team_linode
|
maintainers: $team_linode
|
||||||
labels: cloud linode
|
labels: cloud linode
|
||||||
keywords: linode dynamic inventory script
|
keywords: linode dynamic inventory script
|
||||||
$inventories/proxmox.py:
|
|
||||||
maintainers: $team_virt ilijamt
|
|
||||||
$inventories/scaleway.py:
|
$inventories/scaleway.py:
|
||||||
maintainers: $team_scaleway
|
maintainers: $team_scaleway
|
||||||
labels: cloud scaleway
|
labels: cloud scaleway
|
||||||
@@ -108,6 +128,9 @@ files:
|
|||||||
maintainers: amigus
|
maintainers: amigus
|
||||||
$lookups/dsv.py:
|
$lookups/dsv.py:
|
||||||
maintainers: amigus
|
maintainers: amigus
|
||||||
|
$lookups/hashi_vault.py:
|
||||||
|
labels: hashi_vault
|
||||||
|
maintainers: briantist
|
||||||
$lookups/manifold.py:
|
$lookups/manifold.py:
|
||||||
maintainers: galanoff
|
maintainers: galanoff
|
||||||
labels: manifold
|
labels: manifold
|
||||||
@@ -116,6 +139,11 @@ files:
|
|||||||
labels: infoblox networking
|
labels: infoblox networking
|
||||||
$module_utils/:
|
$module_utils/:
|
||||||
labels: module_utils
|
labels: module_utils
|
||||||
|
$module_utils/docker/:
|
||||||
|
maintainers: $team_docker
|
||||||
|
labels: cloud
|
||||||
|
ignore: cove
|
||||||
|
supershipit: felixfontein
|
||||||
$module_utils/gitlab.py:
|
$module_utils/gitlab.py:
|
||||||
notify: jlozadad
|
notify: jlozadad
|
||||||
maintainers: $team_gitlab
|
maintainers: $team_gitlab
|
||||||
@@ -130,6 +158,10 @@ files:
|
|||||||
$module_utils/ipa.py:
|
$module_utils/ipa.py:
|
||||||
maintainers: $team_ipa
|
maintainers: $team_ipa
|
||||||
labels: ipa
|
labels: ipa
|
||||||
|
$module_utils/kubevirt.py:
|
||||||
|
maintainers: $team_kubevirt
|
||||||
|
labels: cloud kubevirt
|
||||||
|
keywords: kubevirt
|
||||||
$module_utils/manageiq.py:
|
$module_utils/manageiq.py:
|
||||||
maintainers: $team_manageiq
|
maintainers: $team_manageiq
|
||||||
labels: manageiq
|
labels: manageiq
|
||||||
@@ -145,6 +177,10 @@ files:
|
|||||||
$module_utils/oracle/oci_utils.py:
|
$module_utils/oracle/oci_utils.py:
|
||||||
maintainers: $team_oracle
|
maintainers: $team_oracle
|
||||||
labels: cloud
|
labels: cloud
|
||||||
|
$module_utils/postgres.py:
|
||||||
|
maintainers: $team_postgresql
|
||||||
|
labels: postgres postgresql
|
||||||
|
keywords: database postgres postgresql
|
||||||
$module_utils/pure.py:
|
$module_utils/pure.py:
|
||||||
maintainers: $team_purestorage
|
maintainers: $team_purestorage
|
||||||
labels: pure pure_storage
|
labels: pure pure_storage
|
||||||
@@ -176,19 +212,52 @@ files:
|
|||||||
labels: dimensiondata_network
|
labels: dimensiondata_network
|
||||||
$modules/cloud/dimensiondata/dimensiondata_vlan.py:
|
$modules/cloud/dimensiondata/dimensiondata_vlan.py:
|
||||||
maintainers: tintoy
|
maintainers: tintoy
|
||||||
|
$modules/cloud/docker/:
|
||||||
|
maintainers: $team_docker
|
||||||
|
ignore: cove
|
||||||
|
supershipit: felixfontein
|
||||||
|
$modules/cloud/docker/docker_compose.py:
|
||||||
|
maintainers: sluther
|
||||||
|
labels: docker_compose
|
||||||
|
$modules/cloud/docker/docker_config.py:
|
||||||
|
maintainers: ushuz
|
||||||
|
$modules/cloud/docker/docker_container.py:
|
||||||
|
maintainers: dusdanig softzilla zfil
|
||||||
|
ignore: ThomasSteinbach cove joshuaconner
|
||||||
|
$modules/cloud/docker/docker_image.py:
|
||||||
|
maintainers: softzilla ssbarnea
|
||||||
|
$modules/cloud/docker/docker_login.py:
|
||||||
|
maintainers: olsaki
|
||||||
|
$modules/cloud/docker/docker_network.py:
|
||||||
|
maintainers: keitwb
|
||||||
|
labels: docker_network
|
||||||
|
$modules/cloud/docker/docker_stack_task_info.py:
|
||||||
|
maintainers: imjoseangel
|
||||||
|
$modules/cloud/docker/docker_swarm_service.py:
|
||||||
|
maintainers: hannseman
|
||||||
|
labels: docker_swarm_service
|
||||||
|
$modules/cloud/docker/docker_swarm_service_info.py:
|
||||||
|
maintainers: hannseman
|
||||||
|
$modules/cloud/docker/docker_volume.py:
|
||||||
|
maintainers: agronholm
|
||||||
|
$modules/cloud/google/:
|
||||||
|
maintainers: $team_google
|
||||||
|
ignore: supertom
|
||||||
|
supershipit: $team_google
|
||||||
$modules/cloud/heroku/heroku_collaborator.py:
|
$modules/cloud/heroku/heroku_collaborator.py:
|
||||||
maintainers: marns93
|
maintainers: marns93
|
||||||
$modules/cloud/huawei/:
|
$modules/cloud/huawei/:
|
||||||
maintainers: $team_huawei huaweicloud
|
maintainers: $team_huawei huaweicloud
|
||||||
keywords: cloud huawei hwc
|
keywords: cloud huawei hwc
|
||||||
|
$modules/cloud/kubevirt/:
|
||||||
|
maintainers: $team_kubevirt kubevirt
|
||||||
|
keywords: kubevirt
|
||||||
$modules/cloud/linode/:
|
$modules/cloud/linode/:
|
||||||
maintainers: $team_linode
|
maintainers: $team_linode
|
||||||
$modules/cloud/linode/linode.py:
|
$modules/cloud/linode/linode.py:
|
||||||
maintainers: zbal
|
maintainers: zbal
|
||||||
$modules/cloud/lxc/lxc_container.py:
|
$modules/cloud/lxc/lxc_container.py:
|
||||||
maintainers: cloudnull
|
maintainers: cloudnull
|
||||||
$modules/cloud/lxc/lxc_profile.py:
|
|
||||||
maintainers: conloos
|
|
||||||
$modules/cloud/lxd/:
|
$modules/cloud/lxd/:
|
||||||
ignore: hnakamur
|
ignore: hnakamur
|
||||||
$modules/cloud/memset/:
|
$modules/cloud/memset/:
|
||||||
@@ -207,10 +276,6 @@ files:
|
|||||||
labels: proxmox_kvm virt
|
labels: proxmox_kvm virt
|
||||||
ignore: skvidal
|
ignore: skvidal
|
||||||
keywords: kvm libvirt proxmox qemu
|
keywords: kvm libvirt proxmox qemu
|
||||||
$modules/cloud/misc/proxmox_snap.py:
|
|
||||||
maintainers: $team_virt
|
|
||||||
labels: proxmox virt
|
|
||||||
keywords: kvm libvirt proxmox qemu
|
|
||||||
$modules/cloud/misc/proxmox_template.py:
|
$modules/cloud/misc/proxmox_template.py:
|
||||||
maintainers: $team_virt UnderGreen
|
maintainers: $team_virt UnderGreen
|
||||||
labels: proxmox_template virt
|
labels: proxmox_template virt
|
||||||
@@ -224,7 +289,7 @@ files:
|
|||||||
$modules/cloud/misc/:
|
$modules/cloud/misc/:
|
||||||
ignore: ryansb
|
ignore: ryansb
|
||||||
$modules/cloud/misc/terraform.py:
|
$modules/cloud/misc/terraform.py:
|
||||||
maintainers: m-yosefpor rainerleber
|
maintainers: m-yosefpor
|
||||||
$modules/cloud/misc/xenserver_facts.py:
|
$modules/cloud/misc/xenserver_facts.py:
|
||||||
maintainers: caphrim007 cheese
|
maintainers: caphrim007 cheese
|
||||||
labels: xenserver_facts
|
labels: xenserver_facts
|
||||||
@@ -308,10 +373,8 @@ files:
|
|||||||
maintainers: bvitnik
|
maintainers: bvitnik
|
||||||
$modules/clustering/consul/:
|
$modules/clustering/consul/:
|
||||||
maintainers: $team_consul
|
maintainers: $team_consul
|
||||||
ignore: colin-nolan
|
|
||||||
$modules/clustering/etcd3.py:
|
$modules/clustering/etcd3.py:
|
||||||
maintainers: evrardjp
|
maintainers: evrardjp vfauth
|
||||||
ignore: vfauth
|
|
||||||
$modules/clustering/nomad/:
|
$modules/clustering/nomad/:
|
||||||
maintainers: chris93111
|
maintainers: chris93111
|
||||||
$modules/clustering/pacemaker_cluster.py:
|
$modules/clustering/pacemaker_cluster.py:
|
||||||
@@ -341,6 +404,20 @@ files:
|
|||||||
$modules/database/mssql/mssql_db.py:
|
$modules/database/mssql/mssql_db.py:
|
||||||
maintainers: vedit Jmainguy kenichi-ogawa-1988
|
maintainers: vedit Jmainguy kenichi-ogawa-1988
|
||||||
labels: mssql_db
|
labels: mssql_db
|
||||||
|
$modules/database/postgresql/:
|
||||||
|
keywords: database postgres postgresql
|
||||||
|
labels: postgres postgresql
|
||||||
|
maintainers: $team_postgresql
|
||||||
|
$modules/database/postgresql/postgresql_ext.py:
|
||||||
|
maintainers: dschep strk
|
||||||
|
$modules/database/postgresql/postgresql_lang.py:
|
||||||
|
maintainers: jensdepuydt
|
||||||
|
$modules/database/postgresql/postgresql_privs.py:
|
||||||
|
maintainers: b6d
|
||||||
|
$modules/database/postgresql/postgresql_query.py:
|
||||||
|
maintainers: archf wrouesnel
|
||||||
|
$modules/database/postgresql/postgresql_tablespace.py:
|
||||||
|
maintainers: antoinell
|
||||||
$modules/database/vertica/:
|
$modules/database/vertica/:
|
||||||
maintainers: dareko
|
maintainers: dareko
|
||||||
$modules/files/archive.py:
|
$modules/files/archive.py:
|
||||||
@@ -362,8 +439,6 @@ files:
|
|||||||
maintainers: Rylon
|
maintainers: Rylon
|
||||||
$modules/identity/ipa/:
|
$modules/identity/ipa/:
|
||||||
maintainers: $team_ipa
|
maintainers: $team_ipa
|
||||||
$modules/identity/ipa/ipa_pwpolicy.py:
|
|
||||||
maintainers: adralioh
|
|
||||||
$modules/identity/ipa/ipa_service.py:
|
$modules/identity/ipa/ipa_service.py:
|
||||||
maintainers: cprh
|
maintainers: cprh
|
||||||
$modules/identity/ipa/ipa_vault.py:
|
$modules/identity/ipa/ipa_vault.py:
|
||||||
@@ -433,12 +508,8 @@ files:
|
|||||||
maintainers: andsens
|
maintainers: andsens
|
||||||
$modules/monitoring/spectrum_device.py:
|
$modules/monitoring/spectrum_device.py:
|
||||||
maintainers: orgito
|
maintainers: orgito
|
||||||
$modules/monitoring/spectrum_model_attrs.py:
|
|
||||||
maintainers: tgates81
|
|
||||||
$modules/monitoring/stackdriver.py:
|
$modules/monitoring/stackdriver.py:
|
||||||
maintainers: bwhaley
|
maintainers: bwhaley
|
||||||
$modules/monitoring/statsd.py:
|
|
||||||
maintainers: mamercad
|
|
||||||
$modules/monitoring/statusio_maintenance.py:
|
$modules/monitoring/statusio_maintenance.py:
|
||||||
maintainers: bhcopeland
|
maintainers: bhcopeland
|
||||||
$modules/monitoring/uptimerobot.py:
|
$modules/monitoring/uptimerobot.py:
|
||||||
@@ -451,7 +522,15 @@ files:
|
|||||||
$modules/net_tools/dnsmadeeasy.py:
|
$modules/net_tools/dnsmadeeasy.py:
|
||||||
maintainers: briceburg
|
maintainers: briceburg
|
||||||
$modules/net_tools/haproxy.py:
|
$modules/net_tools/haproxy.py:
|
||||||
maintainers: ravibhure Normo
|
maintainers: ravibhure
|
||||||
|
$modules/net_tools/hetzner_failover_ip.py:
|
||||||
|
maintainers: felixfontein
|
||||||
|
$modules/net_tools/hetzner_failover_ip_info.py:
|
||||||
|
maintainers: felixfontein
|
||||||
|
$modules/net_tools/hetzner_firewall.py:
|
||||||
|
maintainers: felixfontein
|
||||||
|
$modules/net_tools/hetzner_firewall_info.py:
|
||||||
|
maintainers: felixfontein
|
||||||
$modules/net_tools/:
|
$modules/net_tools/:
|
||||||
maintainers: nerzhul
|
maintainers: nerzhul
|
||||||
$modules/net_tools/infinity/infinity.py:
|
$modules/net_tools/infinity/infinity.py:
|
||||||
@@ -497,7 +576,7 @@ files:
|
|||||||
$modules/net_tools/nmcli.py:
|
$modules/net_tools/nmcli.py:
|
||||||
maintainers: alcamie101
|
maintainers: alcamie101
|
||||||
$modules/net_tools/snmp_facts.py:
|
$modules/net_tools/snmp_facts.py:
|
||||||
maintainers: ogenstad ujwalkomarla
|
maintainers: ogenstad bigmstone ujwalkomarla
|
||||||
$modules/notification/osx_say.py:
|
$modules/notification/osx_say.py:
|
||||||
maintainers: ansible mpdehaan
|
maintainers: ansible mpdehaan
|
||||||
labels: _osx_say
|
labels: _osx_say
|
||||||
@@ -551,7 +630,7 @@ files:
|
|||||||
$modules/notification/syslogger.py:
|
$modules/notification/syslogger.py:
|
||||||
maintainers: garbled1
|
maintainers: garbled1
|
||||||
$modules/notification/telegram.py:
|
$modules/notification/telegram.py:
|
||||||
maintainers: tyouxa loms
|
maintainers: tyouxa
|
||||||
$modules/notification/twilio.py:
|
$modules/notification/twilio.py:
|
||||||
maintainers: makaimc
|
maintainers: makaimc
|
||||||
$modules/notification/typetalk.py:
|
$modules/notification/typetalk.py:
|
||||||
@@ -561,8 +640,7 @@ files:
|
|||||||
$modules/packaging/language/bundler.py:
|
$modules/packaging/language/bundler.py:
|
||||||
maintainers: thoiberg
|
maintainers: thoiberg
|
||||||
$modules/packaging/language/composer.py:
|
$modules/packaging/language/composer.py:
|
||||||
maintainers: dmtrs
|
maintainers: dmtrs resmo
|
||||||
ignore: resmo
|
|
||||||
$modules/packaging/language/cpanm.py:
|
$modules/packaging/language/cpanm.py:
|
||||||
maintainers: fcuny
|
maintainers: fcuny
|
||||||
$modules/packaging/language/easy_install.py:
|
$modules/packaging/language/easy_install.py:
|
||||||
@@ -591,8 +669,6 @@ files:
|
|||||||
ignore: kbrebanov
|
ignore: kbrebanov
|
||||||
$modules/packaging/os/apt_rpm.py:
|
$modules/packaging/os/apt_rpm.py:
|
||||||
maintainers: evgkrsk
|
maintainers: evgkrsk
|
||||||
$modules/packaging/os/copr.py:
|
|
||||||
maintainers: schlupov
|
|
||||||
$modules/packaging/os/flatpak.py:
|
$modules/packaging/os/flatpak.py:
|
||||||
maintainers: $team_flatpak
|
maintainers: $team_flatpak
|
||||||
$modules/packaging/os/flatpak_remote.py:
|
$modules/packaging/os/flatpak_remote.py:
|
||||||
@@ -679,8 +755,6 @@ files:
|
|||||||
maintainers: seandst
|
maintainers: seandst
|
||||||
$modules/packaging/os/rhsm_repository.py:
|
$modules/packaging/os/rhsm_repository.py:
|
||||||
maintainers: giovannisciortino
|
maintainers: giovannisciortino
|
||||||
$modules/packaging/os/rpm_ostree_pkg.py:
|
|
||||||
maintainers: dustymabe Akasurde
|
|
||||||
$modules/packaging/os/slackpkg.py:
|
$modules/packaging/os/slackpkg.py:
|
||||||
maintainers: KimNorgaard
|
maintainers: KimNorgaard
|
||||||
$modules/packaging/os/snap.py:
|
$modules/packaging/os/snap.py:
|
||||||
@@ -702,16 +776,12 @@ files:
|
|||||||
maintainers: pmakowski
|
maintainers: pmakowski
|
||||||
$modules/packaging/os/xbps.py:
|
$modules/packaging/os/xbps.py:
|
||||||
maintainers: dinoocch the-maldridge
|
maintainers: dinoocch the-maldridge
|
||||||
$modules/packaging/os/yum_versionlock.py:
|
|
||||||
maintainers: florianpaulhoberg aminvakil
|
|
||||||
$modules/packaging/os/zypper.py:
|
$modules/packaging/os/zypper.py:
|
||||||
maintainers: $team_suse
|
maintainers: $team_suse
|
||||||
labels: zypper
|
labels: zypper
|
||||||
ignore: dirtyharrycallahan robinro
|
ignore: dirtyharrycallahan robinro
|
||||||
$modules/packaging/os/zypper_repository.py:
|
$modules/packaging/os/zypper_repository.py:
|
||||||
maintainers: $team_suse
|
maintainers: matze
|
||||||
labels: zypper
|
|
||||||
ignore: matze
|
|
||||||
$modules/remote_management/cobbler/:
|
$modules/remote_management/cobbler/:
|
||||||
maintainers: dagwieers
|
maintainers: dagwieers
|
||||||
$modules/remote_management/dellemc/:
|
$modules/remote_management/dellemc/:
|
||||||
@@ -720,6 +790,8 @@ files:
|
|||||||
maintainers: jagadeeshnv
|
maintainers: jagadeeshnv
|
||||||
$modules/remote_management/dellemc/ome_device_info.py:
|
$modules/remote_management/dellemc/ome_device_info.py:
|
||||||
maintainers: Sajna-Shetty
|
maintainers: Sajna-Shetty
|
||||||
|
$modules/remote_management/foreman/:
|
||||||
|
maintainers: ehelms ares ekohl xprazak2
|
||||||
$modules/remote_management/hpilo/:
|
$modules/remote_management/hpilo/:
|
||||||
maintainers: haad
|
maintainers: haad
|
||||||
ignore: dagwieers
|
ignore: dagwieers
|
||||||
@@ -728,8 +800,6 @@ files:
|
|||||||
labels: cisco
|
labels: cisco
|
||||||
$modules/remote_management/ipmi/:
|
$modules/remote_management/ipmi/:
|
||||||
maintainers: bgaifullin cloudnull
|
maintainers: bgaifullin cloudnull
|
||||||
$modules/remote_management/lenovoxcc/:
|
|
||||||
maintainers: panyy3 renxulei
|
|
||||||
$modules/remote_management/lxca/:
|
$modules/remote_management/lxca/:
|
||||||
maintainers: navalkp prabhosa
|
maintainers: navalkp prabhosa
|
||||||
$modules/remote_management/manageiq/:
|
$modules/remote_management/manageiq/:
|
||||||
@@ -750,7 +820,7 @@ files:
|
|||||||
$modules/remote_management/oneview/oneview_fcoe_network.py:
|
$modules/remote_management/oneview/oneview_fcoe_network.py:
|
||||||
maintainers: fgbulsoni
|
maintainers: fgbulsoni
|
||||||
$modules/remote_management/redfish/:
|
$modules/remote_management/redfish/:
|
||||||
maintainers: $team_redfish
|
maintainers: $team_redfish billdodd
|
||||||
ignore: jose-delarosa
|
ignore: jose-delarosa
|
||||||
$modules/remote_management/stacki/stacki_host.py:
|
$modules/remote_management/stacki/stacki_host.py:
|
||||||
maintainers: bsanders bbyhuy
|
maintainers: bsanders bbyhuy
|
||||||
@@ -763,6 +833,8 @@ files:
|
|||||||
maintainers: andreparames
|
maintainers: andreparames
|
||||||
$modules/source_control/git_config.py:
|
$modules/source_control/git_config.py:
|
||||||
maintainers: djmattyg007 mgedmin
|
maintainers: djmattyg007 mgedmin
|
||||||
|
$modules/source_control/github/github_hooks.py:
|
||||||
|
maintainers: pcgentry
|
||||||
$modules/source_control/github/github_deploy_key.py:
|
$modules/source_control/github/github_deploy_key.py:
|
||||||
maintainers: bincyber
|
maintainers: bincyber
|
||||||
$modules/source_control/github/github_issue.py:
|
$modules/source_control/github/github_issue.py:
|
||||||
@@ -773,8 +845,6 @@ files:
|
|||||||
ignore: erydo
|
ignore: erydo
|
||||||
$modules/source_control/github/github_release.py:
|
$modules/source_control/github/github_release.py:
|
||||||
maintainers: adrianmoisey
|
maintainers: adrianmoisey
|
||||||
$modules/source_control/github/github_repo.py:
|
|
||||||
maintainers: atorrescogollo
|
|
||||||
$modules/source_control/github/:
|
$modules/source_control/github/:
|
||||||
maintainers: stpierre
|
maintainers: stpierre
|
||||||
$modules/source_control/gitlab/:
|
$modules/source_control/gitlab/:
|
||||||
@@ -857,10 +927,8 @@ files:
|
|||||||
labels: interfaces_file
|
labels: interfaces_file
|
||||||
$modules/system/iptables_state.py:
|
$modules/system/iptables_state.py:
|
||||||
maintainers: quidame
|
maintainers: quidame
|
||||||
$modules/system/shutdown.py:
|
|
||||||
maintainers: nitzmahone samdoran aminvakil
|
|
||||||
$modules/system/java_cert.py:
|
$modules/system/java_cert.py:
|
||||||
maintainers: haad absynth76
|
maintainers: haad
|
||||||
$modules/system/java_keystore.py:
|
$modules/system/java_keystore.py:
|
||||||
maintainers: Mogztter
|
maintainers: Mogztter
|
||||||
$modules/system/kernel_blacklist.py:
|
$modules/system/kernel_blacklist.py:
|
||||||
@@ -934,8 +1002,6 @@ files:
|
|||||||
maintainers: bcoca
|
maintainers: bcoca
|
||||||
$modules/system/syspatch.py:
|
$modules/system/syspatch.py:
|
||||||
maintainers: precurse
|
maintainers: precurse
|
||||||
$modules/system/sysrc.py:
|
|
||||||
maintainers: dlundgren
|
|
||||||
$modules/system/sysupgrade.py:
|
$modules/system/sysupgrade.py:
|
||||||
maintainers: precurse
|
maintainers: precurse
|
||||||
$modules/system/timezone.py:
|
$modules/system/timezone.py:
|
||||||
@@ -945,7 +1011,7 @@ files:
|
|||||||
maintainers: ahtik ovcharenko pyykkis
|
maintainers: ahtik ovcharenko pyykkis
|
||||||
labels: ufw
|
labels: ufw
|
||||||
$modules/system/vdo.py:
|
$modules/system/vdo.py:
|
||||||
maintainers: rhawalsh
|
maintainers: bgurney-rh
|
||||||
$modules/system/xfconf.py:
|
$modules/system/xfconf.py:
|
||||||
maintainers: russoz jbenden
|
maintainers: russoz jbenden
|
||||||
labels: xfconf
|
labels: xfconf
|
||||||
@@ -958,13 +1024,11 @@ files:
|
|||||||
$modules/web_infrastructure/apache2_mod_proxy.py:
|
$modules/web_infrastructure/apache2_mod_proxy.py:
|
||||||
maintainers: oboukili
|
maintainers: oboukili
|
||||||
$modules/web_infrastructure/apache2_module.py:
|
$modules/web_infrastructure/apache2_module.py:
|
||||||
maintainers: berendt n0trax
|
maintainers: berendt n0trax robinro
|
||||||
ignore: robinro
|
|
||||||
$modules/web_infrastructure/deploy_helper.py:
|
$modules/web_infrastructure/deploy_helper.py:
|
||||||
maintainers: ramondelafuente
|
maintainers: ramondelafuente
|
||||||
$modules/web_infrastructure/django_manage.py:
|
$modules/web_infrastructure/django_manage.py:
|
||||||
maintainers: russoz
|
maintainers: scottanderson42 russoz tastychutney
|
||||||
ignore: scottanderson42 tastychutney
|
|
||||||
labels: django_manage
|
labels: django_manage
|
||||||
$modules/web_infrastructure/ejabberd_user.py:
|
$modules/web_infrastructure/ejabberd_user.py:
|
||||||
maintainers: privateip
|
maintainers: privateip
|
||||||
@@ -1032,27 +1096,31 @@ macros:
|
|||||||
terminals: plugins/terminal
|
terminals: plugins/terminal
|
||||||
team_aix: MorrisA bcoca d-little flynn1973 gforster kairoaraujo marvin-sinister mator molekuul ramooncamacho wtcross
|
team_aix: MorrisA bcoca d-little flynn1973 gforster kairoaraujo marvin-sinister mator molekuul ramooncamacho wtcross
|
||||||
team_bsd: JoergFiedler MacLemon bcoca dch jasperla mekanix opoplawski overhacked tuxillo
|
team_bsd: JoergFiedler MacLemon bcoca dch jasperla mekanix opoplawski overhacked tuxillo
|
||||||
team_consul: sgargan
|
team_consul: colin-nolan sgargan
|
||||||
team_cyberark_conjur: jvanderhoof ryanprior
|
team_cyberark_conjur: jvanderhoof ryanprior
|
||||||
|
team_docker: DBendit WojciechowskiPiotr akshay196 danihodovic dariko felixfontein jwitko kassiansun tbouvet chouseknecht
|
||||||
team_e_spirit: MatrixCrawler getjack
|
team_e_spirit: MatrixCrawler getjack
|
||||||
team_flatpak: JayKayy oolongbrothers
|
team_flatpak: JayKayy oolongbrothers
|
||||||
team_gitlab: Lunik Shaps dj-wasabi marwatk waheedi zanssa scodeman metanovii
|
team_gitlab: Lunik Shaps dj-wasabi marwatk waheedi zanssa scodeman
|
||||||
|
team_google: erjohnso rambleraptor
|
||||||
team_hpux: bcoca davx8342
|
team_hpux: bcoca davx8342
|
||||||
team_huawei: QijunPan TommyLike edisonxiang freesky-edward hwDCN niuzhenguo xuxiaowei0512 yanzhangi zengchen1024 zhongjun2
|
team_huawei: QijunPan TommyLike edisonxiang freesky-edward hwDCN niuzhenguo xuxiaowei0512 yanzhangi zengchen1024 zhongjun2
|
||||||
team_ipa: Akasurde Nosmoht fxfitz justchris1
|
team_ipa: Akasurde Nosmoht fxfitz
|
||||||
team_jboss: Wolfant jairojunior wbrefvem
|
team_jboss: Wolfant jairojunior wbrefvem
|
||||||
team_keycloak: eikef ndclt
|
team_keycloak: eikef ndclt
|
||||||
team_linode: InTheCloudDan decentral1se displague rmcintosh Charliekenney23 LBGarber
|
team_kubevirt: machacekondra mmazur pkliczewski
|
||||||
|
team_linode: InTheCloudDan decentral1se displague rmcintosh
|
||||||
team_macos: Akasurde kyleabenson martinm82 danieljaouen indrajitr
|
team_macos: Akasurde kyleabenson martinm82 danieljaouen indrajitr
|
||||||
team_manageiq: abellotti cben gtanzillo yaacov zgalor dkorn evertmulder
|
team_manageiq: abellotti cben gtanzillo yaacov zgalor dkorn evertmulder
|
||||||
team_netapp: amit0701 carchi8py hulquest lmprice lonico ndswartz schmots1
|
team_netapp: amit0701 carchi8py hulquest lmprice lonico ndswartz schmots1
|
||||||
team_networking: NilashishC Qalthos danielmellado ganeshrn justjais trishnaguha sganesh-infoblox privateip
|
team_networking: NilashishC Qalthos danielmellado ganeshrn justjais trishnaguha sganesh-infoblox privateip
|
||||||
team_opennebula: ilicmilan meerkampdvv rsmontero xorel nilsding
|
team_opennebula: ilicmilan meerkampdvv rsmontero xorel
|
||||||
team_oracle: manojmeda mross22 nalsaber
|
team_oracle: manojmeda mross22 nalsaber
|
||||||
|
team_postgresql: Andersson007 Dorn- andytom jbscalia kostiantyn-nemchenko matburt nerzhul sebasmannem tcraxs ilicmilan
|
||||||
team_purestorage: bannaych dnix101 genegr lionmax opslounge raekins sdodsley sile16
|
team_purestorage: bannaych dnix101 genegr lionmax opslounge raekins sdodsley sile16
|
||||||
team_redfish: mraineri tomasg2012 xmadsen renxulei
|
team_redfish: billdodd mraineri tomasg2012
|
||||||
team_rhn: FlossWare alikins barnabycourt vritant
|
team_rhn: FlossWare alikins barnabycourt vritant
|
||||||
team_scaleway: QuentinBrosse abarbare jerome-quere kindermoumoute remyleone sieben
|
team_scaleway: QuentinBrosse abarbare jerome-quere kindermoumoute remyleone sieben
|
||||||
team_solaris: bcoca fishman jasperla jpdasma mator scathatheworm troy2914 xen0l
|
team_solaris: bcoca fishman jasperla jpdasma mator scathatheworm troy2914 xen0l
|
||||||
team_suse: commel dcermak evrardjp lrupp toabctl AnderEnder alxgu andytom sealor
|
team_suse: commel dcermak evrardjp lrupp toabctl AnderEnder alxgu andytom
|
||||||
team_virt: joshainglis karmab tleguern Thulium-Drake Ajpantuso
|
team_virt: joshainglis karmab Aversiste
|
||||||
|
|||||||
81
.gitignore
vendored
81
.gitignore
vendored
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
# Created by https://www.toptal.com/developers/gitignore/api/git,linux,pydev,python,windows,pycharm+all,jupyternotebook,vim,webstorm,emacs,dotenv
|
# Created by https://www.gitignore.io/api/git,linux,pydev,python,windows,pycharm+all,jupyternotebook,vim,webstorm,emacs,dotenv
|
||||||
# Edit at https://www.toptal.com/developers/gitignore?templates=git,linux,pydev,python,windows,pycharm+all,jupyternotebook,vim,webstorm,emacs,dotenv
|
# Edit at https://www.gitignore.io/?templates=git,linux,pydev,python,windows,pycharm+all,jupyternotebook,vim,webstorm,emacs,dotenv
|
||||||
|
|
||||||
### dotenv ###
|
### dotenv ###
|
||||||
.env
|
.env
|
||||||
@@ -88,7 +88,7 @@ flycheck_*.el
|
|||||||
.nfs*
|
.nfs*
|
||||||
|
|
||||||
### PyCharm+all ###
|
### PyCharm+all ###
|
||||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
|
||||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
# User-specific stuff
|
# User-specific stuff
|
||||||
@@ -98,9 +98,6 @@ flycheck_*.el
|
|||||||
.idea/**/dictionaries
|
.idea/**/dictionaries
|
||||||
.idea/**/shelf
|
.idea/**/shelf
|
||||||
|
|
||||||
# AWS User-specific
|
|
||||||
.idea/**/aws.xml
|
|
||||||
|
|
||||||
# Generated files
|
# Generated files
|
||||||
.idea/**/contentModel.xml
|
.idea/**/contentModel.xml
|
||||||
|
|
||||||
@@ -121,9 +118,6 @@ flycheck_*.el
|
|||||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||||
# since they will be recreated, and may cause churn. Uncomment if using
|
# since they will be recreated, and may cause churn. Uncomment if using
|
||||||
# auto-import.
|
# auto-import.
|
||||||
# .idea/artifacts
|
|
||||||
# .idea/compiler.xml
|
|
||||||
# .idea/jarRepositories.xml
|
|
||||||
# .idea/modules.xml
|
# .idea/modules.xml
|
||||||
# .idea/*.iml
|
# .idea/*.iml
|
||||||
# .idea/modules
|
# .idea/modules
|
||||||
@@ -204,6 +198,7 @@ parts/
|
|||||||
sdist/
|
sdist/
|
||||||
var/
|
var/
|
||||||
wheels/
|
wheels/
|
||||||
|
pip-wheel-metadata/
|
||||||
share/python-wheels/
|
share/python-wheels/
|
||||||
*.egg-info/
|
*.egg-info/
|
||||||
.installed.cfg
|
.installed.cfg
|
||||||
@@ -230,25 +225,13 @@ htmlcov/
|
|||||||
nosetests.xml
|
nosetests.xml
|
||||||
coverage.xml
|
coverage.xml
|
||||||
*.cover
|
*.cover
|
||||||
*.py,cover
|
|
||||||
.hypothesis/
|
.hypothesis/
|
||||||
.pytest_cache/
|
.pytest_cache/
|
||||||
cover/
|
|
||||||
|
|
||||||
# Translations
|
# Translations
|
||||||
*.mo
|
*.mo
|
||||||
*.pot
|
*.pot
|
||||||
|
|
||||||
# Django stuff:
|
|
||||||
*.log
|
|
||||||
local_settings.py
|
|
||||||
db.sqlite3
|
|
||||||
db.sqlite3-journal
|
|
||||||
|
|
||||||
# Flask stuff:
|
|
||||||
instance/
|
|
||||||
.webassets-cache
|
|
||||||
|
|
||||||
# Scrapy stuff:
|
# Scrapy stuff:
|
||||||
.scrapy
|
.scrapy
|
||||||
|
|
||||||
@@ -256,19 +239,9 @@ instance/
|
|||||||
docs/_build/
|
docs/_build/
|
||||||
|
|
||||||
# PyBuilder
|
# PyBuilder
|
||||||
.pybuilder/
|
|
||||||
target/
|
target/
|
||||||
|
|
||||||
# Jupyter Notebook
|
|
||||||
.ipynb_checkpoints
|
|
||||||
|
|
||||||
# IPython
|
|
||||||
profile_default/
|
|
||||||
ipython_config.py
|
|
||||||
|
|
||||||
# pyenv
|
# pyenv
|
||||||
# For a library or package, you might want to ignore these files since the code is
|
|
||||||
# intended to run in multiple environments; otherwise, check them in:
|
|
||||||
.python-version
|
.python-version
|
||||||
|
|
||||||
# pipenv
|
# pipenv
|
||||||
@@ -278,24 +251,12 @@ ipython_config.py
|
|||||||
# install all needed dependencies.
|
# install all needed dependencies.
|
||||||
#Pipfile.lock
|
#Pipfile.lock
|
||||||
|
|
||||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
# celery beat schedule file
|
||||||
__pypackages__/
|
|
||||||
|
|
||||||
# Celery stuff
|
|
||||||
celerybeat-schedule
|
celerybeat-schedule
|
||||||
celerybeat.pid
|
|
||||||
|
|
||||||
# SageMath parsed files
|
# SageMath parsed files
|
||||||
*.sage.py
|
*.sage.py
|
||||||
|
|
||||||
# Environments
|
|
||||||
.venv
|
|
||||||
env/
|
|
||||||
venv/
|
|
||||||
ENV/
|
|
||||||
env.bak/
|
|
||||||
venv.bak/
|
|
||||||
|
|
||||||
# Spyder project settings
|
# Spyder project settings
|
||||||
.spyderproject
|
.spyderproject
|
||||||
.spyproject
|
.spyproject
|
||||||
@@ -303,6 +264,10 @@ venv.bak/
|
|||||||
# Rope project settings
|
# Rope project settings
|
||||||
.ropeproject
|
.ropeproject
|
||||||
|
|
||||||
|
# Mr Developer
|
||||||
|
.mr.developer.cfg
|
||||||
|
.project
|
||||||
|
|
||||||
# mkdocs documentation
|
# mkdocs documentation
|
||||||
/site
|
/site
|
||||||
|
|
||||||
@@ -314,16 +279,9 @@ dmypy.json
|
|||||||
# Pyre type checker
|
# Pyre type checker
|
||||||
.pyre/
|
.pyre/
|
||||||
|
|
||||||
# pytype static type analyzer
|
|
||||||
.pytype/
|
|
||||||
|
|
||||||
# Cython debug symbols
|
|
||||||
cython_debug/
|
|
||||||
|
|
||||||
### Vim ###
|
### Vim ###
|
||||||
# Swap
|
# Swap
|
||||||
[._]*.s[a-v][a-z]
|
[._]*.s[a-v][a-z]
|
||||||
!*.svg # comment out if you don't need vector files
|
|
||||||
[._]*.sw[a-p]
|
[._]*.sw[a-p]
|
||||||
[._]s[a-rt-v][a-z]
|
[._]s[a-rt-v][a-z]
|
||||||
[._]ss[a-gi-z]
|
[._]ss[a-gi-z]
|
||||||
@@ -341,13 +299,11 @@ tags
|
|||||||
[._]*.un~
|
[._]*.un~
|
||||||
|
|
||||||
### WebStorm ###
|
### WebStorm ###
|
||||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
|
||||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
# User-specific stuff
|
# User-specific stuff
|
||||||
|
|
||||||
# AWS User-specific
|
|
||||||
|
|
||||||
# Generated files
|
# Generated files
|
||||||
|
|
||||||
# Sensitive or high-churn files
|
# Sensitive or high-churn files
|
||||||
@@ -358,9 +314,6 @@ tags
|
|||||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||||
# since they will be recreated, and may cause churn. Uncomment if using
|
# since they will be recreated, and may cause churn. Uncomment if using
|
||||||
# auto-import.
|
# auto-import.
|
||||||
# .idea/artifacts
|
|
||||||
# .idea/compiler.xml
|
|
||||||
# .idea/jarRepositories.xml
|
|
||||||
# .idea/modules.xml
|
# .idea/modules.xml
|
||||||
# .idea/*.iml
|
# .idea/*.iml
|
||||||
# .idea/modules
|
# .idea/modules
|
||||||
@@ -396,27 +349,15 @@ tags
|
|||||||
# *.ipr
|
# *.ipr
|
||||||
|
|
||||||
# Sonarlint plugin
|
# Sonarlint plugin
|
||||||
# https://plugins.jetbrains.com/plugin/7973-sonarlint
|
|
||||||
.idea/**/sonarlint/
|
.idea/**/sonarlint/
|
||||||
|
|
||||||
# SonarQube Plugin
|
# SonarQube Plugin
|
||||||
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
|
|
||||||
.idea/**/sonarIssues.xml
|
.idea/**/sonarIssues.xml
|
||||||
|
|
||||||
# Markdown Navigator plugin
|
# Markdown Navigator plugin
|
||||||
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
|
|
||||||
.idea/**/markdown-navigator.xml
|
.idea/**/markdown-navigator.xml
|
||||||
.idea/**/markdown-navigator-enh.xml
|
|
||||||
.idea/**/markdown-navigator/
|
.idea/**/markdown-navigator/
|
||||||
|
|
||||||
# Cache file creation bug
|
|
||||||
# See https://youtrack.jetbrains.com/issue/JBR-2257
|
|
||||||
.idea/$CACHE_FILE$
|
|
||||||
|
|
||||||
# CodeStream plugin
|
|
||||||
# https://plugins.jetbrains.com/plugin/12206-codestream
|
|
||||||
.idea/codestream.xml
|
|
||||||
|
|
||||||
### Windows ###
|
### Windows ###
|
||||||
# Windows thumbnail cache files
|
# Windows thumbnail cache files
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
@@ -443,4 +384,4 @@ $RECYCLE.BIN/
|
|||||||
# Windows shortcuts
|
# Windows shortcuts
|
||||||
*.lnk
|
*.lnk
|
||||||
|
|
||||||
# End of https://www.toptal.com/developers/gitignore/api/git,linux,pydev,python,windows,pycharm+all,jupyternotebook,vim,webstorm,emacs,dotenv
|
# End of https://www.gitignore.io/api/git,linux,pydev,python,windows,pycharm+all,jupyternotebook,vim,webstorm,emacs,dotenv
|
||||||
|
|||||||
1971
CHANGELOG.rst
1971
CHANGELOG.rst
File diff suppressed because it is too large
Load Diff
@@ -1,36 +0,0 @@
|
|||||||
# Contributing
|
|
||||||
|
|
||||||
We follow [Ansible Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html) in all our contributions and interactions within this repository.
|
|
||||||
|
|
||||||
If you are a committer, also refer to the [collection's committer guidelines](https://github.com/ansible-collections/community.general/blob/main/commit-rights.md).
|
|
||||||
|
|
||||||
## Issue tracker
|
|
||||||
|
|
||||||
Whether you are looking for an opportunity to contribute or you found a bug and already know how to solve it, please go to the [issue tracker](https://github.com/ansible-collections/community.general/issues).
|
|
||||||
There you can find feature ideas to implement, reports about bugs to solve, or submit an issue to discuss your idea before implementing it which can help choose a right direction at the beginning of your work and potentially save a lot of time and effort.
|
|
||||||
Also somebody may already have started discussing or working on implementing the same or a similar idea,
|
|
||||||
so you can cooperate to create a better solution together.
|
|
||||||
|
|
||||||
* If you are interested in starting with an easy issue, look for [issues with an `easyfix` label](https://github.com/ansible-collections/community.general/labels/easyfix).
|
|
||||||
* Often issues that are waiting for contributors to pick up have [the `waiting_on_contributor` label](https://github.com/ansible-collections/community.general/labels/waiting_on_contributor).
|
|
||||||
|
|
||||||
## Open pull requests
|
|
||||||
|
|
||||||
Look through currently [open pull requests](https://github.com/ansible-collections/community.general/pulls).
|
|
||||||
You can help by reviewing them. Reviews help move pull requests to merge state. Some good pull requests cannot be merged only due to a lack of reviews. And it is always worth saying that good reviews are often more valuable than pull requests themselves.
|
|
||||||
Note that reviewing does not only mean code review, but also offering comments on new interfaces added to existing plugins/modules, interfaces of new plugins/modules, improving language (not everyone is a native english speaker), or testing bugfixes and new features!
|
|
||||||
|
|
||||||
Also, consider taking up a valuable, reviewed, but abandoned pull request which you could politely ask the original authors to complete yourself.
|
|
||||||
|
|
||||||
* Try committing your changes with an informative but short commit message.
|
|
||||||
* Do not squash your commits and force-push to your branch if not needed. Reviews of your pull request are much easier with individual commits to comprehend the pull request history. All commits of your pull request branch will be squashed into one commit by GitHub upon merge.
|
|
||||||
* Do not add merge commits to your PR. The bot will complain and you will have to rebase ([instructions for rebasing](https://docs.ansible.com/ansible/latest/dev_guide/developing_rebasing.html)) to remove them before your PR can be merged. To avoid that git automatically does merges during pulls, you can configure it to do rebases instead by running `git config pull.rebase true` inside the respository checkout.
|
|
||||||
* Make sure your PR includes a [changelog fragment](https://docs.ansible.com/ansible/devel/community/development_process.html#changelogs-how-to). (You must not include a fragment for new modules or new plugins, except for test and filter plugins. Also you shouldn't include one for docs-only changes. If you're not sure, simply don't include one, we'll tell you whether one is needed or not :) )
|
|
||||||
|
|
||||||
You can also read [our Quick-start development guide](https://github.com/ansible/community-docs/blob/main/create_pr_quick_start_guide.rst).
|
|
||||||
|
|
||||||
## Test pull requests
|
|
||||||
|
|
||||||
If you want to test a PR locally, refer to [our testing guide](https://github.com/ansible/community-docs/blob/main/test_pr_locally_guide.rst) for instructions on how do it quickly.
|
|
||||||
|
|
||||||
If you find any inconsistencies or places in this document which can be improved, feel free to raise an issue or pull request to fix it.
|
|
||||||
88
README.md
88
README.md
@@ -1,23 +1,15 @@
|
|||||||
# Community General Collection
|
# Community General Collection
|
||||||
|
|
||||||
[](https://dev.azure.com/ansible/community.general/_build?definitionId=31)
|
[](https://dev.azure.com/ansible/community.general/_build?definitionId=31)
|
||||||
[](https://codecov.io/gh/ansible-collections/community.general)
|
[](https://codecov.io/gh/ansible-collections/community.general)
|
||||||
|
|
||||||
This repository contains the `community.general` Ansible Collection. The collection is a part of the Ansible package and includes many modules and plugins supported by Ansible community which are not part of more specialized community collections.
|
This repo contains the `community.general` Ansible Collection. The collection includes many modules and plugins supported by Ansible community which are not part of more specialized community collections.
|
||||||
|
|
||||||
You can find [documentation for this collection on the Ansible docs site](https://docs.ansible.com/ansible/latest/collections/community/general/).
|
You can find [documentation for this collection on the Ansible docs site](https://docs.ansible.com/ansible/latest/collections/community/general/).
|
||||||
|
|
||||||
Please note that this collection does **not** support Windows targets. Only connection plugins included in this collection might support Windows targets, and will explicitly mention that in their documentation if they do so.
|
|
||||||
|
|
||||||
## Code of Conduct
|
|
||||||
|
|
||||||
We follow [Ansible Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html) in all our interactions within this project.
|
|
||||||
|
|
||||||
If you encounter abusive behavior violating the [Ansible Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html), please refer to the [policy violations](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html#policy-violations) section of the Code of Conduct for information on how to raise a complaint.
|
|
||||||
|
|
||||||
## Tested with Ansible
|
## Tested with Ansible
|
||||||
|
|
||||||
Tested with the current Ansible 2.9, ansible-base 2.10, ansible-core 2.11 and ansible-core 2.12 releases. Ansible versions before 2.9.10 are not supported.
|
Tested with the current Ansible 2.9 and 2.10 releases and the current development version of Ansible. Ansible versions before 2.9.10 are not supported.
|
||||||
|
|
||||||
## External requirements
|
## External requirements
|
||||||
|
|
||||||
@@ -29,9 +21,7 @@ Please check the included content on the [Ansible Galaxy page for this collectio
|
|||||||
|
|
||||||
## Using this collection
|
## Using this collection
|
||||||
|
|
||||||
This collection is shipped with the Ansible package. So if you have it installed, no more action is required.
|
Before using the General community collection, you need to install the collection with the `ansible-galaxy` CLI:
|
||||||
|
|
||||||
If you have a minimal installation (only Ansible Core installed) or you want to use the latest version of the collection along with the whole Ansible package, you need to install the collection from [Ansible Galaxy](https://galaxy.ansible.com/community/general) manually with the `ansible-galaxy` command-line tool:
|
|
||||||
|
|
||||||
ansible-galaxy collection install community.general
|
ansible-galaxy collection install community.general
|
||||||
|
|
||||||
@@ -42,79 +32,57 @@ collections:
|
|||||||
- name: community.general
|
- name: community.general
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that if you install the collection manually, it will not be upgraded automatically when you upgrade the Ansible package. To upgrade the collection to the latest available version, run the following command:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ansible-galaxy collection install community.general --upgrade
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also install a specific version of the collection, for example, if you need to downgrade when something is broken in the latest version (please report an issue in this repository). Use the following syntax where `X.Y.Z` can be any [available version](https://galaxy.ansible.com/community/general):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ansible-galaxy collection install community.general:==X.Y.Z
|
|
||||||
```
|
|
||||||
|
|
||||||
See [Ansible Using collections](https://docs.ansible.com/ansible/latest/user_guide/collections_using.html) for more details.
|
See [Ansible Using collections](https://docs.ansible.com/ansible/latest/user_guide/collections_using.html) for more details.
|
||||||
|
|
||||||
## Contributing to this collection
|
## Contributing to this collection
|
||||||
|
|
||||||
The content of this collection is made by good people just like you, a community of individuals collaborating on making the world better through developing automation software.
|
If you want to develop new content for this collection or improve what is already here, the easiest way to work on the collection is to clone it into one of the configured [`COLLECTIONS_PATH`](https://docs.ansible.com/ansible/latest/reference_appendices/config.html#collections-paths), and work on it there.
|
||||||
|
|
||||||
We are actively accepting new contributors.
|
For example, if you are working in the `~/dev` directory:
|
||||||
|
|
||||||
All types of contributions are very welcome.
|
```
|
||||||
|
cd ~/dev
|
||||||
You don't know how to start? Refer to our [contribution guide](https://github.com/ansible-collections/community.general/blob/main/CONTRIBUTING.md)!
|
git clone git@github.com:ansible-collections/community.general.git collections/ansible_collections/community/general
|
||||||
|
export COLLECTIONS_PATH=$(pwd)/collections:$COLLECTIONS_PATH
|
||||||
The current maintainers are listed in the [commit-rights.md](https://github.com/ansible-collections/community.general/blob/main/commit-rights.md#people) file. If you have questions or need help, feel free to mention them in the proposals.
|
```
|
||||||
|
|
||||||
You can find more information in the [developer guide for collections](https://docs.ansible.com/ansible/devel/dev_guide/developing_collections.html#contributing-to-collections), and in the [Ansible Community Guide](https://docs.ansible.com/ansible/latest/community/index.html).
|
You can find more information in the [developer guide for collections](https://docs.ansible.com/ansible/devel/dev_guide/developing_collections.html#contributing-to-collections), and in the [Ansible Community Guide](https://docs.ansible.com/ansible/latest/community/index.html).
|
||||||
|
|
||||||
Also for some notes specific to this collection see [our CONTRIBUTING documentation](https://github.com/ansible-collections/community.general/blob/main/CONTRIBUTING.md).
|
|
||||||
|
|
||||||
### Running tests
|
### Running tests
|
||||||
|
|
||||||
See [here](https://docs.ansible.com/ansible/devel/dev_guide/developing_collections.html#testing-collections).
|
See [here](https://docs.ansible.com/ansible/devel/dev_guide/developing_collections.html#testing-collections).
|
||||||
|
|
||||||
## Collection maintenance
|
### Communication
|
||||||
|
|
||||||
To learn how to maintain / become a maintainer of this collection, refer to:
|
We have a dedicated Working Group for Ansible development.
|
||||||
|
|
||||||
* [Committer guidelines](https://github.com/ansible-collections/community.general/blob/main/commit-rights.md).
|
You can find other people interested on the following Freenode IRC channels -
|
||||||
* [Maintainer guidelines](https://github.com/ansible/community-docs/blob/main/maintaining.rst).
|
- `#ansible` - For general use questions and support.
|
||||||
|
- `#ansible-devel` - For discussions on developer topics and code related to features or bugs.
|
||||||
It is necessary for maintainers of this collection to be subscribed to:
|
- `#ansible-community` - For discussions on community topics and community meetings.
|
||||||
|
|
||||||
* The collection itself (the `Watch` button → `All Activity` in the upper right corner of the repository's homepage).
|
|
||||||
* The "Changes Impacting Collection Contributors and Maintainers" [issue](https://github.com/ansible-collections/overview/issues/45).
|
|
||||||
|
|
||||||
They also should be subscribed to Ansible's [The Bullhorn newsletter](https://docs.ansible.com/ansible/devel/community/communication.html#the-bullhorn).
|
|
||||||
|
|
||||||
## Communication
|
|
||||||
|
|
||||||
We announce important development changes and releases through Ansible's [The Bullhorn newsletter](https://eepurl.com/gZmiEP). If you are a collection developer, be sure you are subscribed.
|
|
||||||
|
|
||||||
Join us in the `#ansible` (general use questions and support), `#ansible-community` (community and collection development questions), and other [IRC channels](https://docs.ansible.com/ansible/devel/community/communication.html#irc-channels) on [Libera.chat](https://libera.chat).
|
|
||||||
|
|
||||||
We take part in the global quarterly [Ansible Contributor Summit](https://github.com/ansible/community/wiki/Contributor-Summit) virtually or in-person. Track [The Bullhorn newsletter](https://eepurl.com/gZmiEP) and join us.
|
|
||||||
|
|
||||||
For more information about communities, meetings and agendas see [Community Wiki](https://github.com/ansible/community/wiki/Community).
|
For more information about communities, meetings and agendas see [Community Wiki](https://github.com/ansible/community/wiki/Community).
|
||||||
|
|
||||||
For more information about communication, refer to Ansible's the [Communication guide](https://docs.ansible.com/ansible/devel/community/communication.html).
|
For more information about [communication](https://docs.ansible.com/ansible/latest/community/communication.html)
|
||||||
|
|
||||||
## Publishing New Version
|
### Publishing New Version
|
||||||
|
|
||||||
See the [Releasing guidelines](https://github.com/ansible/community-docs/blob/main/releasing_collections.rst) to learn how to release this collection.
|
Basic instructions without release branches:
|
||||||
|
|
||||||
|
1. Create `changelogs/fragments/<version>.yml` with `release_summary:` section (which must be a string, not a list).
|
||||||
|
2. Run `antsibull-changelog release --collection-flatmap yes`
|
||||||
|
3. Make sure `CHANGELOG.rst` and `changelogs/changelog.yaml` are added to git, and the deleted fragments have been removed.
|
||||||
|
4. Tag the commit with `<version>`. Push changes and tag to the main repository.
|
||||||
|
|
||||||
## Release notes
|
## Release notes
|
||||||
|
|
||||||
See the [changelog](https://github.com/ansible-collections/community.general/blob/stable-2/CHANGELOG.rst).
|
See the [changelog](https://github.com/ansible-collections/community.general/blob/main/CHANGELOG.rst).
|
||||||
|
|
||||||
## Roadmap
|
## Roadmap
|
||||||
|
|
||||||
In general, we plan to release a major version every six months, and minor versions every two months. Major versions can contain breaking changes, while minor versions only contain new features and bugfixes.
|
See [this issue](https://github.com/ansible-collections/community.general/issues/582) for information on releasing, versioning and deprecation.
|
||||||
|
|
||||||
See [this issue](https://github.com/ansible-collections/community.general/issues/582) for information on releasing, versioning, and deprecation.
|
In general, we plan to release a major version every six months, and minor versions every two months. Major versions can contain breaking changes, while minor versions only contain new features and bugfixes.
|
||||||
|
|
||||||
## More information
|
## More information
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,74 +0,0 @@
|
|||||||
Committers Guidelines for community.general
|
|
||||||
===========================================
|
|
||||||
|
|
||||||
This document is based on the [Ansible committer guidelines](https://github.com/ansible/ansible/blob/b57444af14062ec96e0af75fdfc2098c74fe2d9a/docs/docsite/rst/community/committer_guidelines.rst) ([latest version](https://docs.ansible.com/ansible/devel/community/committer_guidelines.html)).
|
|
||||||
|
|
||||||
These are the guidelines for people with commit privileges on the Ansible Community General Collection GitHub repository. Please read the guidelines before you commit.
|
|
||||||
|
|
||||||
These guidelines apply to everyone. At the same time, this is NOT a process document. So just use good judgment. You have been given commit access because we trust your judgment.
|
|
||||||
|
|
||||||
That said, use the trust wisely.
|
|
||||||
|
|
||||||
If you abuse the trust and break components and builds, and so on, the trust level falls and you may be asked not to commit or you may lose your commit privileges.
|
|
||||||
|
|
||||||
Our workflow on GitHub
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
As a committer, you may already know this, but our workflow forms a lot of our team policies. Please ensure you are aware of the following workflow steps:
|
|
||||||
|
|
||||||
* Fork the repository upon which you want to do some work to your own personal repository
|
|
||||||
* Work on the specific branch upon which you need to commit
|
|
||||||
* Create a Pull Request back to the collection repository and await reviews
|
|
||||||
* Adjust code as necessary based on the Comments provided
|
|
||||||
* Ask someone from the other committers to do a final review and merge
|
|
||||||
|
|
||||||
Sometimes, committers merge their own pull requests. This section is a set of guidelines. If you are changing a comma in a doc or making a very minor change, you can use your best judgement. This is another trust thing. The process is critical for any major change, but for little things or getting something done quickly, use your best judgement and make sure people on the team are aware of your work.
|
|
||||||
|
|
||||||
Roles
|
|
||||||
-----
|
|
||||||
* Release managers: Merge pull requests to `stable-X` branches, create tags to do releases.
|
|
||||||
* Committers: Fine to do PRs for most things, but we should have a timebox. Hanging PRs may merge on the judgement of these devs.
|
|
||||||
* Module maintainers: Module maintainers own specific modules and have indirect commit access through the current module PR mechanisms. This is primary [ansibullbot](https://github.com/ansibullbot)'s `shipit` mechanism.
|
|
||||||
|
|
||||||
General rules
|
|
||||||
-------------
|
|
||||||
Individuals with direct commit access to this collection repository are entrusted with powers that allow them to do a broad variety of things--probably more than we can write down. Rather than rules, treat these as general *guidelines*, individuals with this power are expected to use their best judgement.
|
|
||||||
|
|
||||||
* Do NOTs:
|
|
||||||
|
|
||||||
- Do not commit directly.
|
|
||||||
- Do not merge your own PRs. Someone else should have a chance to review and approve the PR merge. You have a small amount of leeway here for very minor changes.
|
|
||||||
- Do not forget about non-standard / alternate environments. Consider the alternatives. Yes, people have bad/unusual/strange environments (like binaries from multiple init systems installed), but they are the ones who need us the most.
|
|
||||||
- Do not drag your community team members down. Discuss the technical merits of any pull requests you review. Avoid negativity and personal comments. For more guidance on being a good community member, read the [Ansible Community Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html).
|
|
||||||
- Do not forget about the maintenance burden. High-maintenance features may not be worth adding.
|
|
||||||
- Do not break playbooks. Always keep backwards compatibility in mind.
|
|
||||||
- Do not forget to keep it simple. Complexity breeds all kinds of problems.
|
|
||||||
- Do not merge to branches other than `main`, especially not to `stable-X`, if you do not have explicit permission to do so.
|
|
||||||
- Do not create tags. Tags are used in the release process, and should only be created by the people responsible for managing the stable branches.
|
|
||||||
|
|
||||||
* Do:
|
|
||||||
|
|
||||||
- Squash, avoid merges whenever possible, use GitHub's squash commits or cherry pick if needed (bisect thanks you).
|
|
||||||
- Be active. Committers who have no activity on the project (through merges, triage, commits, and so on) will have their permissions suspended.
|
|
||||||
- Consider backwards compatibility (goes back to "do not break existing playbooks").
|
|
||||||
- Write tests. PRs with tests are looked at with more priority than PRs without tests that should have them included. While not all changes require tests, be sure to add them for bug fixes or functionality changes.
|
|
||||||
- Discuss with other committers, specially when you are unsure of something.
|
|
||||||
- Document! If your PR is a new feature or a change to behavior, make sure you've updated all associated documentation or have notified the right people to do so.
|
|
||||||
- Consider scope, sometimes a fix can be generalized.
|
|
||||||
- Keep it simple, then things are maintainable, debuggable and intelligible.
|
|
||||||
|
|
||||||
Committers are expected to continue to follow the same community and contribution guidelines followed by the rest of the Ansible community.
|
|
||||||
|
|
||||||
|
|
||||||
People
|
|
||||||
------
|
|
||||||
|
|
||||||
Individuals who have been asked to become a part of this group have generally been contributing in significant ways to the community.general collection for some time. Should they agree, they are requested to add their names and GitHub IDs to this file, in the section below, through a pull request. Doing so indicates that these individuals agree to act in the ways that their fellow committers trust that they will act.
|
|
||||||
|
|
||||||
| Name | GitHub ID | IRC Nick | Other |
|
|
||||||
| ------------------- | -------------------- | ------------------ | -------------------- |
|
|
||||||
| Alexei Znamensky | russoz | russoz | |
|
|
||||||
| Andrew Klychkov | andersson007 | andersson007_ | |
|
|
||||||
| Andrew Pantuso | Ajpantuso | ajpantuso | |
|
|
||||||
| Felix Fontein | felixfontein | felixfontein | |
|
|
||||||
| John R Barker | gundalow | gundalow | |
|
|
||||||
@@ -1,14 +1,17 @@
|
|||||||
namespace: community
|
namespace: community
|
||||||
name: general
|
name: general
|
||||||
version: 2.5.7
|
version: 1.3.2
|
||||||
readme: README.md
|
readme: README.md
|
||||||
authors:
|
authors:
|
||||||
- Ansible (https://github.com/ansible)
|
- Ansible (https://github.com/ansible)
|
||||||
description: null
|
description: null
|
||||||
license_file: COPYING
|
license_file: COPYING
|
||||||
tags: [community]
|
tags: [community]
|
||||||
# NOTE: No dependencies are expected to be added here
|
# NOTE: No more dependencies can be added to this list
|
||||||
# dependencies:
|
dependencies:
|
||||||
|
ansible.netcommon: '>=1.0.0'
|
||||||
|
community.kubernetes: '>=1.0.0'
|
||||||
|
google.cloud: '>=1.0.0'
|
||||||
repository: https://github.com/ansible-collections/community.general
|
repository: https://github.com/ansible-collections/community.general
|
||||||
documentation: https://docs.ansible.com/ansible/latest/collections/community/general/
|
documentation: https://docs.ansible.com/ansible/latest/collections/community/general/
|
||||||
homepage: https://github.com/ansible-collections/community.general
|
homepage: https://github.com/ansible-collections/community.general
|
||||||
|
|||||||
789
meta/runtime.yml
789
meta/runtime.yml
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# Copyright: (c) 2020, quidame <quidame@poivron.org>
|
# Copyright: (c) 2020, quidame <quidame@poivron.org>
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
@@ -8,7 +7,7 @@ __metaclass__ = type
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
from ansible.plugins.action import ActionBase
|
from ansible.plugins.action import ActionBase
|
||||||
from ansible.errors import AnsibleActionFail, AnsibleConnectionFailure
|
from ansible.errors import AnsibleError, AnsibleActionFail, AnsibleConnectionFailure
|
||||||
from ansible.utils.vars import merge_hash
|
from ansible.utils.vars import merge_hash
|
||||||
from ansible.utils.display import Display
|
from ansible.utils.display import Display
|
||||||
|
|
||||||
@@ -41,27 +40,19 @@ class ActionModule(ActionBase):
|
|||||||
"(=%s) to 0, and 'async' (=%s) to a value >2 and not greater than "
|
"(=%s) to 0, and 'async' (=%s) to a value >2 and not greater than "
|
||||||
"'ansible_timeout' (=%s) (recommended).")
|
"'ansible_timeout' (=%s) (recommended).")
|
||||||
|
|
||||||
def _async_result(self, async_status_args, task_vars, timeout):
|
def _async_result(self, module_args, task_vars, timeout):
|
||||||
'''
|
'''
|
||||||
Retrieve results of the asynchonous task, and display them in place of
|
Retrieve results of the asynchonous task, and display them in place of
|
||||||
the async wrapper results (those with the ansible_job_id key).
|
the async wrapper results (those with the ansible_job_id key).
|
||||||
'''
|
'''
|
||||||
async_status = self._task.copy()
|
|
||||||
async_status.args = async_status_args
|
|
||||||
async_status.action = 'ansible.builtin.async_status'
|
|
||||||
async_status.async_val = 0
|
|
||||||
async_action = self._shared_loader_obj.action_loader.get(
|
|
||||||
async_status.action, task=async_status, connection=self._connection,
|
|
||||||
play_context=self._play_context, loader=self._loader, templar=self._templar,
|
|
||||||
shared_loader_obj=self._shared_loader_obj)
|
|
||||||
|
|
||||||
if async_status.args['mode'] == 'cleanup':
|
|
||||||
return async_action.run(task_vars=task_vars)
|
|
||||||
|
|
||||||
# At least one iteration is required, even if timeout is 0.
|
# At least one iteration is required, even if timeout is 0.
|
||||||
for dummy in range(max(1, timeout)):
|
for i in range(max(1, timeout)):
|
||||||
async_result = async_action.run(task_vars=task_vars)
|
async_result = self._execute_module(
|
||||||
if async_result.get('finished', 0) == 1:
|
module_name='ansible.builtin.async_status',
|
||||||
|
module_args=module_args,
|
||||||
|
task_vars=task_vars,
|
||||||
|
wrap_async=False)
|
||||||
|
if async_result['finished'] == 1:
|
||||||
break
|
break
|
||||||
time.sleep(min(1, timeout))
|
time.sleep(min(1, timeout))
|
||||||
|
|
||||||
@@ -85,6 +76,7 @@ class ActionModule(ActionBase):
|
|||||||
task_async = self._task.async_val
|
task_async = self._task.async_val
|
||||||
check_mode = self._play_context.check_mode
|
check_mode = self._play_context.check_mode
|
||||||
max_timeout = self._connection._play_context.timeout
|
max_timeout = self._connection._play_context.timeout
|
||||||
|
module_name = self._task.action
|
||||||
module_args = self._task.args
|
module_args = self._task.args
|
||||||
|
|
||||||
if module_args.get('state', None) == 'restored':
|
if module_args.get('state', None) == 'restored':
|
||||||
@@ -106,16 +98,32 @@ class ActionModule(ActionBase):
|
|||||||
task_async,
|
task_async,
|
||||||
max_timeout))
|
max_timeout))
|
||||||
|
|
||||||
# inject the async directory based on the shell option into the
|
# BEGIN snippet from async_status action plugin
|
||||||
# module args
|
env_async_dir = [e for e in self._task.environment if
|
||||||
async_dir = self.get_shell_option('async_dir', default="~/.ansible_async")
|
"ANSIBLE_ASYNC_DIR" in e]
|
||||||
|
if len(env_async_dir) > 0:
|
||||||
|
# for backwards compatibility we need to get the dir from
|
||||||
|
# ANSIBLE_ASYNC_DIR that is defined in the environment. This is
|
||||||
|
# deprecated and will be removed in favour of shell options
|
||||||
|
async_dir = env_async_dir[0]['ANSIBLE_ASYNC_DIR']
|
||||||
|
|
||||||
|
msg = "Setting the async dir from the environment keyword " \
|
||||||
|
"ANSIBLE_ASYNC_DIR is deprecated. Set the async_dir " \
|
||||||
|
"shell option instead"
|
||||||
|
display.deprecated(msg, version='2.0.0',
|
||||||
|
collection_name='community.general') # was Ansible 2.12
|
||||||
|
else:
|
||||||
|
# inject the async directory based on the shell option into the
|
||||||
|
# module args
|
||||||
|
async_dir = self.get_shell_option('async_dir', default="~/.ansible_async")
|
||||||
|
# END snippet from async_status action plugin
|
||||||
|
|
||||||
# Bind the loop max duration to consistent values on both
|
# Bind the loop max duration to consistent values on both
|
||||||
# remote and local sides (if not the same, make the loop
|
# remote and local sides (if not the same, make the loop
|
||||||
# longer on the controller); and set a backup file path.
|
# longer on the controller); and set a backup file path.
|
||||||
module_args['_timeout'] = task_async
|
module_args['_timeout'] = task_async
|
||||||
module_args['_back'] = '%s/iptables.state' % async_dir
|
module_args['_back'] = '%s/iptables.state' % async_dir
|
||||||
async_status_args = dict(mode='status')
|
async_status_args = dict(_async_dir=async_dir)
|
||||||
confirm_cmd = 'rm -f %s' % module_args['_back']
|
confirm_cmd = 'rm -f %s' % module_args['_back']
|
||||||
starter_cmd = 'touch %s.starter' % module_args['_back']
|
starter_cmd = 'touch %s.starter' % module_args['_back']
|
||||||
remaining_time = max(task_async, max_timeout)
|
remaining_time = max(task_async, max_timeout)
|
||||||
@@ -141,7 +149,7 @@ class ActionModule(ActionBase):
|
|||||||
# The module is aware to not process the main iptables-restore
|
# The module is aware to not process the main iptables-restore
|
||||||
# command before finding (and deleting) the 'starter' cookie on
|
# command before finding (and deleting) the 'starter' cookie on
|
||||||
# the host, so the previous query will not reach ssh timeout.
|
# the host, so the previous query will not reach ssh timeout.
|
||||||
dummy = self._low_level_execute_command(starter_cmd, sudoable=self.DEFAULT_SUDOABLE)
|
garbage = self._low_level_execute_command(starter_cmd, sudoable=self.DEFAULT_SUDOABLE)
|
||||||
|
|
||||||
# As the main command is not yet executed on the target, here
|
# As the main command is not yet executed on the target, here
|
||||||
# 'finished' means 'failed before main command be executed'.
|
# 'finished' means 'failed before main command be executed'.
|
||||||
@@ -151,7 +159,7 @@ class ActionModule(ActionBase):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
for dummy in range(max_timeout):
|
for x in range(max_timeout):
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
remaining_time -= 1
|
remaining_time -= 1
|
||||||
# - AnsibleConnectionFailure covers rejected requests (i.e.
|
# - AnsibleConnectionFailure covers rejected requests (i.e.
|
||||||
@@ -159,7 +167,7 @@ class ActionModule(ActionBase):
|
|||||||
# - ansible_timeout is able to cover dropped requests (due
|
# - ansible_timeout is able to cover dropped requests (due
|
||||||
# to a rule or policy DROP) if not lower than async_val.
|
# to a rule or policy DROP) if not lower than async_val.
|
||||||
try:
|
try:
|
||||||
dummy = self._low_level_execute_command(confirm_cmd, sudoable=self.DEFAULT_SUDOABLE)
|
garbage = self._low_level_execute_command(confirm_cmd, sudoable=self.DEFAULT_SUDOABLE)
|
||||||
break
|
break
|
||||||
except AnsibleConnectionFailure:
|
except AnsibleConnectionFailure:
|
||||||
continue
|
continue
|
||||||
@@ -172,12 +180,16 @@ class ActionModule(ActionBase):
|
|||||||
del result[key]
|
del result[key]
|
||||||
|
|
||||||
if result.get('invocation', {}).get('module_args'):
|
if result.get('invocation', {}).get('module_args'):
|
||||||
for key in ('_back', '_timeout', '_async_dir', 'jid'):
|
if '_timeout' in result['invocation']['module_args']:
|
||||||
if result['invocation']['module_args'].get(key):
|
del result['invocation']['module_args']['_back']
|
||||||
del result['invocation']['module_args'][key]
|
del result['invocation']['module_args']['_timeout']
|
||||||
|
|
||||||
async_status_args['mode'] = 'cleanup'
|
async_status_args['mode'] = 'cleanup'
|
||||||
dummy = self._async_result(async_status_args, task_vars, 0)
|
garbage = self._execute_module(
|
||||||
|
module_name='ansible.builtin.async_status',
|
||||||
|
module_args=async_status_args,
|
||||||
|
task_vars=task_vars,
|
||||||
|
wrap_async=False)
|
||||||
|
|
||||||
if not wrap_async:
|
if not wrap_async:
|
||||||
# remove a temporary path we created
|
# remove a temporary path we created
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# Copyright: (c) 2020, Amin Vakil <info@aminvakil.com>
|
# Copyright: (c) 2020, Amin Vakil <info@aminvakil.com>
|
||||||
# Copyright: (c) 2016-2018, Matt Davis <mdavis@ansible.com>
|
# Copyright: (c) 2016-2018, Matt Davis <mdavis@ansible.com>
|
||||||
# Copyright: (c) 2018, Sam Doran <sdoran@redhat.com>
|
# Copyright: (c) 2018, Sam Doran <sdoran@redhat.com>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from __future__ import (absolute_import, division, print_function)
|
|||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
name: doas
|
become: doas
|
||||||
short_description: Do As user
|
short_description: Do As user
|
||||||
description:
|
description:
|
||||||
- This become plugins allows your remote/login user to execute commands as another user via the doas utility.
|
- This become plugins allows your remote/login user to execute commands as another user via the doas utility.
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from __future__ import (absolute_import, division, print_function)
|
|||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
name: dzdo
|
become: dzdo
|
||||||
short_description: Centrify's Direct Authorize
|
short_description: Centrify's Direct Authorize
|
||||||
description:
|
description:
|
||||||
- This become plugins allows your remote/login user to execute commands as another user via the dzdo utility.
|
- This become plugins allows your remote/login user to execute commands as another user via the dzdo utility.
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from __future__ import (absolute_import, division, print_function)
|
|||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
name: ksu
|
become: ksu
|
||||||
short_description: Kerberos substitute user
|
short_description: Kerberos substitute user
|
||||||
description:
|
description:
|
||||||
- This become plugins allows your remote/login user to execute commands as another user via the ksu utility.
|
- This become plugins allows your remote/login user to execute commands as another user via the ksu utility.
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from __future__ import (absolute_import, division, print_function)
|
|||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
name: machinectl
|
become: machinectl
|
||||||
short_description: Systemd's machinectl privilege escalation
|
short_description: Systemd's machinectl privilege escalation
|
||||||
description:
|
description:
|
||||||
- This become plugins allows your remote/login user to execute commands as another user via the machinectl utility.
|
- This become plugins allows your remote/login user to execute commands as another user via the machinectl utility.
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from __future__ import (absolute_import, division, print_function)
|
|||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
name: pbrun
|
become: pbrun
|
||||||
short_description: PowerBroker run
|
short_description: PowerBroker run
|
||||||
description:
|
description:
|
||||||
- This become plugins allows your remote/login user to execute commands as another user via the pbrun utility.
|
- This become plugins allows your remote/login user to execute commands as another user via the pbrun utility.
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from __future__ import (absolute_import, division, print_function)
|
|||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
name: pfexec
|
become: pfexec
|
||||||
short_description: profile based execution
|
short_description: profile based execution
|
||||||
description:
|
description:
|
||||||
- This become plugins allows your remote/login user to execute commands as another user via the pfexec utility.
|
- This become plugins allows your remote/login user to execute commands as another user via the pfexec utility.
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from __future__ import (absolute_import, division, print_function)
|
|||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
name: pmrun
|
become: pmrun
|
||||||
short_description: Privilege Manager run
|
short_description: Privilege Manager run
|
||||||
description:
|
description:
|
||||||
- This become plugins allows your remote/login user to execute commands as another user via the pmrun utility.
|
- This become plugins allows your remote/login user to execute commands as another user via the pmrun utility.
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from __future__ import (absolute_import, division, print_function)
|
|||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
name: sesu
|
become: sesu
|
||||||
short_description: CA Privileged Access Manager
|
short_description: CA Privileged Access Manager
|
||||||
description:
|
description:
|
||||||
- This become plugins allows your remote/login user to execute commands as another user via the sesu utility.
|
- This become plugins allows your remote/login user to execute commands as another user via the sesu utility.
|
||||||
|
|||||||
@@ -1,91 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright: (c) 2021, Ansible Project
|
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
from __future__ import (absolute_import, division, print_function)
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
DOCUMENTATION = """
|
|
||||||
name: sudosu
|
|
||||||
short_description: Run tasks using sudo su -
|
|
||||||
description:
|
|
||||||
- This become plugins allows your remote/login user to execute commands as another user via the C(sudo) and C(su) utilities combined.
|
|
||||||
author:
|
|
||||||
- Dag Wieers (@dagwieers)
|
|
||||||
version_added: 2.4.0
|
|
||||||
options:
|
|
||||||
become_user:
|
|
||||||
description: User you 'become' to execute the task.
|
|
||||||
default: root
|
|
||||||
ini:
|
|
||||||
- section: privilege_escalation
|
|
||||||
key: become_user
|
|
||||||
- section: sudo_become_plugin
|
|
||||||
key: user
|
|
||||||
vars:
|
|
||||||
- name: ansible_become_user
|
|
||||||
- name: ansible_sudo_user
|
|
||||||
env:
|
|
||||||
- name: ANSIBLE_BECOME_USER
|
|
||||||
- name: ANSIBLE_SUDO_USER
|
|
||||||
become_flags:
|
|
||||||
description: Options to pass to C(sudo).
|
|
||||||
default: -H -S -n
|
|
||||||
ini:
|
|
||||||
- section: privilege_escalation
|
|
||||||
key: become_flags
|
|
||||||
- section: sudo_become_plugin
|
|
||||||
key: flags
|
|
||||||
vars:
|
|
||||||
- name: ansible_become_flags
|
|
||||||
- name: ansible_sudo_flags
|
|
||||||
env:
|
|
||||||
- name: ANSIBLE_BECOME_FLAGS
|
|
||||||
- name: ANSIBLE_SUDO_FLAGS
|
|
||||||
become_pass:
|
|
||||||
description: Password to pass to C(sudo).
|
|
||||||
required: false
|
|
||||||
vars:
|
|
||||||
- name: ansible_become_password
|
|
||||||
- name: ansible_become_pass
|
|
||||||
- name: ansible_sudo_pass
|
|
||||||
env:
|
|
||||||
- name: ANSIBLE_BECOME_PASS
|
|
||||||
- name: ANSIBLE_SUDO_PASS
|
|
||||||
ini:
|
|
||||||
- section: sudo_become_plugin
|
|
||||||
key: password
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
from ansible.plugins.become import BecomeBase
|
|
||||||
|
|
||||||
|
|
||||||
class BecomeModule(BecomeBase):
|
|
||||||
|
|
||||||
name = 'community.general.sudosu'
|
|
||||||
|
|
||||||
# messages for detecting prompted password issues
|
|
||||||
fail = ('Sorry, try again.',)
|
|
||||||
missing = ('Sorry, a password is required to run sudo', 'sudo: a password is required')
|
|
||||||
|
|
||||||
def build_become_command(self, cmd, shell):
|
|
||||||
super(BecomeModule, self).build_become_command(cmd, shell)
|
|
||||||
|
|
||||||
if not cmd:
|
|
||||||
return cmd
|
|
||||||
|
|
||||||
becomecmd = 'sudo'
|
|
||||||
|
|
||||||
flags = self.get_option('become_flags') or ''
|
|
||||||
prompt = ''
|
|
||||||
if self.get_option('become_pass'):
|
|
||||||
self.prompt = '[sudo via ansible, key=%s] password:' % self._id
|
|
||||||
if flags: # this could be simplified, but kept as is for now for backwards string matching
|
|
||||||
flags = flags.replace('-n', '')
|
|
||||||
prompt = '-p "%s"' % (self.prompt)
|
|
||||||
|
|
||||||
user = self.get_option('become_user') or ''
|
|
||||||
if user:
|
|
||||||
user = '%s' % (user)
|
|
||||||
|
|
||||||
return ' '.join([becomecmd, flags, prompt, 'su -l', user, self._build_success_command(cmd, shell)])
|
|
||||||
20
plugins/cache/memcached.py
vendored
20
plugins/cache/memcached.py
vendored
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# (c) 2014, Brian Coca, Josh Drake, et al
|
# (c) 2014, Brian Coca, Josh Drake, et al
|
||||||
# (c) 2017 Ansible Project
|
# (c) 2017 Ansible Project
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
@@ -8,7 +7,7 @@ __metaclass__ = type
|
|||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
author: Unknown (!UNKNOWN)
|
author: Unknown (!UNKNOWN)
|
||||||
name: memcached
|
cache: memcached
|
||||||
short_description: Use memcached DB for cache
|
short_description: Use memcached DB for cache
|
||||||
description:
|
description:
|
||||||
- This cache uses JSON formatted, per host records saved in memcached.
|
- This cache uses JSON formatted, per host records saved in memcached.
|
||||||
@@ -54,7 +53,6 @@ from ansible import constants as C
|
|||||||
from ansible.errors import AnsibleError
|
from ansible.errors import AnsibleError
|
||||||
from ansible.module_utils.common._collections_compat import MutableSet
|
from ansible.module_utils.common._collections_compat import MutableSet
|
||||||
from ansible.plugins.cache import BaseCacheModule
|
from ansible.plugins.cache import BaseCacheModule
|
||||||
from ansible.release import __version__ as ansible_base_version
|
|
||||||
from ansible.utils.display import Display
|
from ansible.utils.display import Display
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -154,16 +152,16 @@ class CacheModuleKeys(MutableSet):
|
|||||||
def __len__(self):
|
def __len__(self):
|
||||||
return len(self._keyset)
|
return len(self._keyset)
|
||||||
|
|
||||||
def add(self, value):
|
def add(self, key):
|
||||||
self._keyset[value] = time.time()
|
self._keyset[key] = time.time()
|
||||||
self._cache.set(self.PREFIX, self._keyset)
|
self._cache.set(self.PREFIX, self._keyset)
|
||||||
|
|
||||||
def discard(self, value):
|
def discard(self, key):
|
||||||
del self._keyset[value]
|
del self._keyset[key]
|
||||||
self._cache.set(self.PREFIX, self._keyset)
|
self._cache.set(self.PREFIX, self._keyset)
|
||||||
|
|
||||||
def remove_by_timerange(self, s_min, s_max):
|
def remove_by_timerange(self, s_min, s_max):
|
||||||
for k in list(self._keyset.keys()):
|
for k in self._keyset.keys():
|
||||||
t = self._keyset[k]
|
t = self._keyset[k]
|
||||||
if s_min < t < s_max:
|
if s_min < t < s_max:
|
||||||
del self._keyset[k]
|
del self._keyset[k]
|
||||||
@@ -182,9 +180,9 @@ class CacheModule(BaseCacheModule):
|
|||||||
self._timeout = self.get_option('_timeout')
|
self._timeout = self.get_option('_timeout')
|
||||||
self._prefix = self.get_option('_prefix')
|
self._prefix = self.get_option('_prefix')
|
||||||
except KeyError:
|
except KeyError:
|
||||||
# TODO: remove once we no longer support Ansible 2.9
|
display.deprecated('Rather than importing CacheModules directly, '
|
||||||
if not ansible_base_version.startswith('2.9.'):
|
'use ansible.plugins.loader.cache_loader',
|
||||||
raise AnsibleError("Do not import CacheModules directly. Use ansible.plugins.loader.cache_loader instead.")
|
version='2.0.0', collection_name='community.general') # was Ansible 2.12
|
||||||
if C.CACHE_PLUGIN_CONNECTION:
|
if C.CACHE_PLUGIN_CONNECTION:
|
||||||
connection = C.CACHE_PLUGIN_CONNECTION.split(',')
|
connection = C.CACHE_PLUGIN_CONNECTION.split(',')
|
||||||
self._timeout = C.CACHE_PLUGIN_TIMEOUT
|
self._timeout = C.CACHE_PLUGIN_TIMEOUT
|
||||||
|
|||||||
3
plugins/cache/pickle.py
vendored
3
plugins/cache/pickle.py
vendored
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# (c) 2017, Brian Coca
|
# (c) 2017, Brian Coca
|
||||||
# (c) 2017 Ansible Project
|
# (c) 2017 Ansible Project
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
@@ -8,7 +7,7 @@ from __future__ import (absolute_import, division, print_function)
|
|||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
name: pickle
|
cache: pickle
|
||||||
short_description: Pickle formatted files.
|
short_description: Pickle formatted files.
|
||||||
description:
|
description:
|
||||||
- This cache uses Python's pickle serialization format, in per host files, saved to the filesystem.
|
- This cache uses Python's pickle serialization format, in per host files, saved to the filesystem.
|
||||||
|
|||||||
30
plugins/cache/redis.py
vendored
30
plugins/cache/redis.py
vendored
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# (c) 2014, Brian Coca, Josh Drake, et al
|
# (c) 2014, Brian Coca, Josh Drake, et al
|
||||||
# (c) 2017 Ansible Project
|
# (c) 2017 Ansible Project
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
@@ -7,7 +6,7 @@ __metaclass__ = type
|
|||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
author: Unknown (!UNKNOWN)
|
author: Unknown (!UNKNOWN)
|
||||||
name: redis
|
cache: redis
|
||||||
short_description: Use Redis DB for cache
|
short_description: Use Redis DB for cache
|
||||||
description:
|
description:
|
||||||
- This cache uses JSON formatted, per host records saved in Redis.
|
- This cache uses JSON formatted, per host records saved in Redis.
|
||||||
@@ -62,7 +61,6 @@ DOCUMENTATION = '''
|
|||||||
type: integer
|
type: integer
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import re
|
|
||||||
import time
|
import time
|
||||||
import json
|
import json
|
||||||
|
|
||||||
@@ -71,7 +69,6 @@ from ansible.errors import AnsibleError
|
|||||||
from ansible.module_utils._text import to_native
|
from ansible.module_utils._text import to_native
|
||||||
from ansible.parsing.ajson import AnsibleJSONEncoder, AnsibleJSONDecoder
|
from ansible.parsing.ajson import AnsibleJSONEncoder, AnsibleJSONDecoder
|
||||||
from ansible.plugins.cache import BaseCacheModule
|
from ansible.plugins.cache import BaseCacheModule
|
||||||
from ansible.release import __version__ as ansible_base_version
|
|
||||||
from ansible.utils.display import Display
|
from ansible.utils.display import Display
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -93,8 +90,6 @@ class CacheModule(BaseCacheModule):
|
|||||||
performance.
|
performance.
|
||||||
"""
|
"""
|
||||||
_sentinel_service_name = None
|
_sentinel_service_name = None
|
||||||
re_url_conn = re.compile(r'^([^:]+|\[[^]]+\]):(\d+):(\d+)(?::(.*))?$')
|
|
||||||
re_sent_conn = re.compile(r'^(.*):(\d+)$')
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
uri = ''
|
uri = ''
|
||||||
@@ -108,9 +103,9 @@ class CacheModule(BaseCacheModule):
|
|||||||
self._keys_set = self.get_option('_keyset_name')
|
self._keys_set = self.get_option('_keyset_name')
|
||||||
self._sentinel_service_name = self.get_option('_sentinel_service_name')
|
self._sentinel_service_name = self.get_option('_sentinel_service_name')
|
||||||
except KeyError:
|
except KeyError:
|
||||||
# TODO: remove once we no longer support Ansible 2.9
|
display.deprecated('Rather than importing CacheModules directly, '
|
||||||
if not ansible_base_version.startswith('2.9.'):
|
'use ansible.plugins.loader.cache_loader',
|
||||||
raise AnsibleError("Do not import CacheModules directly. Use ansible.plugins.loader.cache_loader instead.")
|
version='2.0.0', collection_name='community.general') # was Ansible 2.12
|
||||||
if C.CACHE_PLUGIN_CONNECTION:
|
if C.CACHE_PLUGIN_CONNECTION:
|
||||||
uri = C.CACHE_PLUGIN_CONNECTION
|
uri = C.CACHE_PLUGIN_CONNECTION
|
||||||
self._timeout = float(C.CACHE_PLUGIN_TIMEOUT)
|
self._timeout = float(C.CACHE_PLUGIN_TIMEOUT)
|
||||||
@@ -134,18 +129,11 @@ class CacheModule(BaseCacheModule):
|
|||||||
self._db = self._get_sentinel_connection(uri, kw)
|
self._db = self._get_sentinel_connection(uri, kw)
|
||||||
# normal connection
|
# normal connection
|
||||||
else:
|
else:
|
||||||
connection = self._parse_connection(self.re_url_conn, uri)
|
connection = uri.split(':')
|
||||||
self._db = StrictRedis(*connection, **kw)
|
self._db = StrictRedis(*connection, **kw)
|
||||||
|
|
||||||
display.vv('Redis connection: %s' % self._db)
|
display.vv('Redis connection: %s' % self._db)
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _parse_connection(re_patt, uri):
|
|
||||||
match = re_patt.match(uri)
|
|
||||||
if not match:
|
|
||||||
raise AnsibleError("Unable to parse connection string")
|
|
||||||
return match.groups()
|
|
||||||
|
|
||||||
def _get_sentinel_connection(self, uri, kw):
|
def _get_sentinel_connection(self, uri, kw):
|
||||||
"""
|
"""
|
||||||
get sentinel connection details from _uri
|
get sentinel connection details from _uri
|
||||||
@@ -169,7 +157,7 @@ class CacheModule(BaseCacheModule):
|
|||||||
except IndexError:
|
except IndexError:
|
||||||
pass # password is optional
|
pass # password is optional
|
||||||
|
|
||||||
sentinels = [self._parse_connection(self.re_sent_conn, shost) for shost in connections]
|
sentinels = [tuple(shost.split(':')) for shost in connections]
|
||||||
display.vv('\nUsing redis sentinels: %s' % sentinels)
|
display.vv('\nUsing redis sentinels: %s' % sentinels)
|
||||||
scon = Sentinel(sentinels, **kw)
|
scon = Sentinel(sentinels, **kw)
|
||||||
try:
|
try:
|
||||||
@@ -228,12 +216,14 @@ class CacheModule(BaseCacheModule):
|
|||||||
self._db.zrem(self._keys_set, key)
|
self._db.zrem(self._keys_set, key)
|
||||||
|
|
||||||
def flush(self):
|
def flush(self):
|
||||||
for key in list(self.keys()):
|
for key in self.keys():
|
||||||
self.delete(key)
|
self.delete(key)
|
||||||
|
|
||||||
def copy(self):
|
def copy(self):
|
||||||
# TODO: there is probably a better way to do this in redis
|
# TODO: there is probably a better way to do this in redis
|
||||||
ret = dict([(k, self.get(k)) for k in self.keys()])
|
ret = dict()
|
||||||
|
for key in self.keys():
|
||||||
|
ret[key] = self.get(key)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
|
|||||||
3
plugins/cache/yaml.py
vendored
3
plugins/cache/yaml.py
vendored
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# (c) 2017, Brian Coca
|
# (c) 2017, Brian Coca
|
||||||
# (c) 2017 Ansible Project
|
# (c) 2017 Ansible Project
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
@@ -8,7 +7,7 @@ from __future__ import (absolute_import, division, print_function)
|
|||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
name: yaml
|
cache: yaml
|
||||||
short_description: YAML formatted files.
|
short_description: YAML formatted files.
|
||||||
description:
|
description:
|
||||||
- This cache uses YAML formatted, per host, files saved to the filesystem.
|
- This cache uses YAML formatted, per host, files saved to the filesystem.
|
||||||
|
|||||||
61
plugins/callback/actionable.py
Normal file
61
plugins/callback/actionable.py
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
# (c) 2015, Andrew Gaffney <andrew@agaffney.org>
|
||||||
|
# (c) 2017 Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
# Make coding more python3-ish
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
DOCUMENTATION = '''
|
||||||
|
author: Unknown (!UNKNOWN)
|
||||||
|
callback: actionable
|
||||||
|
type: stdout
|
||||||
|
short_description: shows only items that need attention
|
||||||
|
description:
|
||||||
|
- Use this callback when you dont care about OK nor Skipped.
|
||||||
|
- This callback suppresses any non Failed or Changed status.
|
||||||
|
deprecated:
|
||||||
|
why: The 'default' callback plugin now supports this functionality
|
||||||
|
removed_in: '2.0.0' # was Ansible 2.11
|
||||||
|
alternative: "'default' callback plugin with 'display_skipped_hosts = no' and 'display_ok_hosts = no' options"
|
||||||
|
extends_documentation_fragment:
|
||||||
|
- default_callback
|
||||||
|
requirements:
|
||||||
|
- set as stdout callback in configuration
|
||||||
|
# Override defaults from 'default' callback plugin
|
||||||
|
options:
|
||||||
|
display_skipped_hosts:
|
||||||
|
name: Show skipped hosts
|
||||||
|
description: "Toggle to control displaying skipped task/host results in a task"
|
||||||
|
type: bool
|
||||||
|
default: no
|
||||||
|
env:
|
||||||
|
- name: DISPLAY_SKIPPED_HOSTS
|
||||||
|
deprecated:
|
||||||
|
why: environment variables without "ANSIBLE_" prefix are deprecated
|
||||||
|
version: "2.0.0" # was Ansible 2.12
|
||||||
|
alternatives: the "ANSIBLE_DISPLAY_SKIPPED_HOSTS" environment variable
|
||||||
|
- name: ANSIBLE_DISPLAY_SKIPPED_HOSTS
|
||||||
|
ini:
|
||||||
|
- key: display_skipped_hosts
|
||||||
|
section: defaults
|
||||||
|
display_ok_hosts:
|
||||||
|
name: Show 'ok' hosts
|
||||||
|
description: "Toggle to control displaying 'ok' task/host results in a task"
|
||||||
|
type: bool
|
||||||
|
default: no
|
||||||
|
env:
|
||||||
|
- name: ANSIBLE_DISPLAY_OK_HOSTS
|
||||||
|
ini:
|
||||||
|
- key: display_ok_hosts
|
||||||
|
section: defaults
|
||||||
|
'''
|
||||||
|
|
||||||
|
from ansible.plugins.callback.default import CallbackModule as CallbackModule_default
|
||||||
|
|
||||||
|
|
||||||
|
class CallbackModule(CallbackModule_default):
|
||||||
|
|
||||||
|
CALLBACK_VERSION = 2.0
|
||||||
|
CALLBACK_TYPE = 'stdout'
|
||||||
|
CALLBACK_NAME = 'community.general.actionable'
|
||||||
@@ -8,7 +8,7 @@ __metaclass__ = type
|
|||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
author: Unknown (!UNKNOWN)
|
author: Unknown (!UNKNOWN)
|
||||||
name: cgroup_memory_recap
|
callback: cgroup_memory_recap
|
||||||
type: aggregate
|
type: aggregate
|
||||||
requirements:
|
requirements:
|
||||||
- whitelist in configuration
|
- whitelist in configuration
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# (C) 2012, Michael DeHaan, <michael.dehaan@gmail.com>
|
# (C) 2012, Michael DeHaan, <michael.dehaan@gmail.com>
|
||||||
# (c) 2017 Ansible Project
|
# (c) 2017 Ansible Project
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
@@ -8,7 +7,7 @@ __metaclass__ = type
|
|||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
author: Unknown (!UNKNOWN)
|
author: Unknown (!UNKNOWN)
|
||||||
name: context_demo
|
callback: context_demo
|
||||||
type: aggregate
|
type: aggregate
|
||||||
short_description: demo callback that adds play/task context
|
short_description: demo callback that adds play/task context
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# (c) 2018, Ivan Aragones Muniesa <ivan.aragones.muniesa@gmail.com>
|
# (c) 2018, Ivan Aragones Muniesa <ivan.aragones.muniesa@gmail.com>
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
'''
|
'''
|
||||||
@@ -10,7 +9,7 @@ __metaclass__ = type
|
|||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
author: Unknown (!UNKNOWN)
|
author: Unknown (!UNKNOWN)
|
||||||
name: counter_enabled
|
callback: counter_enabled
|
||||||
type: stdout
|
type: stdout
|
||||||
short_description: adds counters to the output items (tasks and hosts/task)
|
short_description: adds counters to the output items (tasks and hosts/task)
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# (c) 2016, Dag Wieers <dag@wieers.com>
|
# (c) 2016, Dag Wieers <dag@wieers.com>
|
||||||
# (c) 2017 Ansible Project
|
# (c) 2017 Ansible Project
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
@@ -7,7 +6,7 @@ from __future__ import (absolute_import, division, print_function)
|
|||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
name: dense
|
callback: dense
|
||||||
type: stdout
|
type: stdout
|
||||||
short_description: minimal stdout output
|
short_description: minimal stdout output
|
||||||
extends_documentation_fragment:
|
extends_documentation_fragment:
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from __future__ import (absolute_import, division, print_function)
|
|||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = r'''
|
DOCUMENTATION = r'''
|
||||||
name: diy
|
callback: diy
|
||||||
type: stdout
|
type: stdout
|
||||||
short_description: Customize the output
|
short_description: Customize the output
|
||||||
version_added: 0.2.0
|
version_added: 0.2.0
|
||||||
@@ -1013,7 +1013,7 @@ class CallbackModule(Default):
|
|||||||
for attr in _stats_attributes:
|
for attr in _stats_attributes:
|
||||||
_ret[self.DIY_NS]['stats'].update({attr: _get_value(obj=stats, attr=attr)})
|
_ret[self.DIY_NS]['stats'].update({attr: _get_value(obj=stats, attr=attr)})
|
||||||
|
|
||||||
_ret[self.DIY_NS].update({'top_level_var_names': list(_ret.keys())})
|
_ret[self.DIY_NS].update({'top_level_var_names': _ret.keys()})
|
||||||
|
|
||||||
return _ret
|
return _ret
|
||||||
|
|
||||||
|
|||||||
76
plugins/callback/full_skip.py
Normal file
76
plugins/callback/full_skip.py
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
# (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com>
|
||||||
|
# (c) 2017 Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
# Make coding more python3-ish
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
DOCUMENTATION = '''
|
||||||
|
author: Unknown (!UNKNOWN)
|
||||||
|
callback: full_skip
|
||||||
|
type: stdout
|
||||||
|
short_description: suppresses tasks if all hosts skipped
|
||||||
|
description:
|
||||||
|
- Use this plugin when you do not care about any output for tasks that were completely skipped
|
||||||
|
deprecated:
|
||||||
|
why: The 'default' callback plugin now supports this functionality
|
||||||
|
removed_in: '2.0.0' # was Ansible 2.11
|
||||||
|
alternative: "'default' callback plugin with 'display_skipped_hosts = no' option"
|
||||||
|
extends_documentation_fragment:
|
||||||
|
- default_callback
|
||||||
|
requirements:
|
||||||
|
- set as stdout in configuration
|
||||||
|
'''
|
||||||
|
|
||||||
|
from ansible.plugins.callback.default import CallbackModule as CallbackModule_default
|
||||||
|
|
||||||
|
|
||||||
|
class CallbackModule(CallbackModule_default):
|
||||||
|
|
||||||
|
'''
|
||||||
|
This is the default callback interface, which simply prints messages
|
||||||
|
to stdout when new callback events are received.
|
||||||
|
'''
|
||||||
|
|
||||||
|
CALLBACK_VERSION = 2.0
|
||||||
|
CALLBACK_TYPE = 'stdout'
|
||||||
|
CALLBACK_NAME = 'community.general.full_skip'
|
||||||
|
|
||||||
|
def v2_runner_on_skipped(self, result):
|
||||||
|
self.outlines = []
|
||||||
|
|
||||||
|
def v2_playbook_item_on_skipped(self, result):
|
||||||
|
self.outlines = []
|
||||||
|
|
||||||
|
def v2_runner_item_on_skipped(self, result):
|
||||||
|
self.outlines = []
|
||||||
|
|
||||||
|
def v2_runner_on_failed(self, result, ignore_errors=False):
|
||||||
|
self.display()
|
||||||
|
super(CallbackModule, self).v2_runner_on_failed(result, ignore_errors)
|
||||||
|
|
||||||
|
def v2_playbook_on_task_start(self, task, is_conditional):
|
||||||
|
self.outlines = []
|
||||||
|
self.outlines.append("TASK [%s]" % task.get_name().strip())
|
||||||
|
if self._display.verbosity >= 2:
|
||||||
|
path = task.get_path()
|
||||||
|
if path:
|
||||||
|
self.outlines.append("task path: %s" % path)
|
||||||
|
|
||||||
|
def v2_playbook_item_on_ok(self, result):
|
||||||
|
self.display()
|
||||||
|
super(CallbackModule, self).v2_playbook_item_on_ok(result)
|
||||||
|
|
||||||
|
def v2_runner_on_ok(self, result):
|
||||||
|
self.display()
|
||||||
|
super(CallbackModule, self).v2_runner_on_ok(result)
|
||||||
|
|
||||||
|
def display(self):
|
||||||
|
if len(self.outlines) == 0:
|
||||||
|
return
|
||||||
|
(first, rest) = self.outlines[0], self.outlines[1:]
|
||||||
|
self._display.banner(first)
|
||||||
|
for line in rest:
|
||||||
|
self._display.display(line)
|
||||||
|
self.outlines = []
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# (C) 2014, Matt Martz <matt@sivel.net>
|
# (C) 2014, Matt Martz <matt@sivel.net>
|
||||||
# (c) 2017 Ansible Project
|
# (c) 2017 Ansible Project
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
@@ -8,7 +7,7 @@ __metaclass__ = type
|
|||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
author: Unknown (!UNKNOWN)
|
author: Unknown (!UNKNOWN)
|
||||||
name: hipchat
|
callback: hipchat
|
||||||
type: notification
|
type: notification
|
||||||
requirements:
|
requirements:
|
||||||
- whitelist in configuration.
|
- whitelist in configuration.
|
||||||
@@ -174,7 +173,8 @@ class CallbackModule(CallbackBase):
|
|||||||
# Displays info about playbook being started by a person on an
|
# Displays info about playbook being started by a person on an
|
||||||
# inventory, as well as Tags, Skip Tags and Limits
|
# inventory, as well as Tags, Skip Tags and Limits
|
||||||
if not self.printed_playbook:
|
if not self.printed_playbook:
|
||||||
self.playbook_name, dummy = os.path.splitext(os.path.basename(self.play.playbook.filename))
|
self.playbook_name, _ = os.path.splitext(
|
||||||
|
os.path.basename(self.play.playbook.filename))
|
||||||
host_list = self.play.playbook.inventory.host_list
|
host_list = self.play.playbook.inventory.host_list
|
||||||
inventory = os.path.basename(os.path.realpath(host_list))
|
inventory = os.path.basename(os.path.realpath(host_list))
|
||||||
self.send_msg("%s: Playbook initiated by %s against %s" %
|
self.send_msg("%s: Playbook initiated by %s against %s" %
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# Copyright (C) 2016 maxn nikolaev.makc@gmail.com
|
# Copyright (C) 2016 maxn nikolaev.makc@gmail.com
|
||||||
# Copyright (c) 2017 Ansible Project
|
# Copyright (c) 2017 Ansible Project
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
@@ -8,7 +7,7 @@ __metaclass__ = type
|
|||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
author: Unknown (!UNKNOWN)
|
author: Unknown (!UNKNOWN)
|
||||||
name: jabber
|
callback: jabber
|
||||||
type: notification
|
type: notification
|
||||||
short_description: post task events to a jabber server
|
short_description: post task events to a jabber server
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# (C) 2012, Michael DeHaan, <michael.dehaan@gmail.com>
|
# (C) 2012, Michael DeHaan, <michael.dehaan@gmail.com>
|
||||||
# (c) 2017 Ansible Project
|
# (c) 2017 Ansible Project
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
@@ -8,7 +7,7 @@ __metaclass__ = type
|
|||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
author: Unknown (!UNKNOWN)
|
author: Unknown (!UNKNOWN)
|
||||||
name: log_plays
|
callback: log_plays
|
||||||
type: notification
|
type: notification
|
||||||
short_description: write playbook output to log file
|
short_description: write playbook output to log file
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -1,235 +0,0 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
|
|
||||||
from __future__ import (absolute_import, division, print_function)
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
|
||||||
name: loganalytics
|
|
||||||
type: aggregate
|
|
||||||
short_description: Posts task results to Azure Log Analytics
|
|
||||||
author: "Cyrus Li (@zhcli) <cyrus1006@gmail.com>"
|
|
||||||
description:
|
|
||||||
- This callback plugin will post task results in JSON formatted to an Azure Log Analytics workspace.
|
|
||||||
- Credits to authors of splunk callback plugin.
|
|
||||||
version_added: "2.4.0"
|
|
||||||
requirements:
|
|
||||||
- Whitelisting this callback plugin.
|
|
||||||
- An Azure log analytics work space has been established.
|
|
||||||
options:
|
|
||||||
workspace_id:
|
|
||||||
description: Workspace ID of the Azure log analytics workspace.
|
|
||||||
required: true
|
|
||||||
env:
|
|
||||||
- name: WORKSPACE_ID
|
|
||||||
ini:
|
|
||||||
- section: callback_loganalytics
|
|
||||||
key: workspace_id
|
|
||||||
shared_key:
|
|
||||||
description: Shared key to connect to Azure log analytics workspace.
|
|
||||||
required: true
|
|
||||||
env:
|
|
||||||
- name: WORKSPACE_SHARED_KEY
|
|
||||||
ini:
|
|
||||||
- section: callback_loganalytics
|
|
||||||
key: shared_key
|
|
||||||
'''
|
|
||||||
|
|
||||||
EXAMPLES = '''
|
|
||||||
examples: |
|
|
||||||
Whitelist the plugin in ansible.cfg:
|
|
||||||
[defaults]
|
|
||||||
callback_whitelist = community.general.loganalytics
|
|
||||||
Set the environment variable:
|
|
||||||
export WORKSPACE_ID=01234567-0123-0123-0123-01234567890a
|
|
||||||
export WORKSPACE_SHARED_KEY=dZD0kCbKl3ehZG6LHFMuhtE0yHiFCmetzFMc2u+roXIUQuatqU924SsAAAAPemhjbGlAemhjbGktTUJQAQIDBA==
|
|
||||||
Or configure the plugin in ansible.cfg in the callback_loganalytics block:
|
|
||||||
[callback_loganalytics]
|
|
||||||
workspace_id = 01234567-0123-0123-0123-01234567890a
|
|
||||||
shared_key = dZD0kCbKl3ehZG6LHFMuhtE0yHiFCmetzFMc2u+roXIUQuatqU924SsAAAAPemhjbGlAemhjbGktTUJQAQIDBA==
|
|
||||||
'''
|
|
||||||
|
|
||||||
import hashlib
|
|
||||||
import hmac
|
|
||||||
import base64
|
|
||||||
import logging
|
|
||||||
import json
|
|
||||||
import uuid
|
|
||||||
import socket
|
|
||||||
import getpass
|
|
||||||
|
|
||||||
from datetime import datetime
|
|
||||||
from os.path import basename
|
|
||||||
|
|
||||||
from ansible.module_utils.urls import open_url
|
|
||||||
from ansible.parsing.ajson import AnsibleJSONEncoder
|
|
||||||
from ansible.plugins.callback import CallbackBase
|
|
||||||
|
|
||||||
|
|
||||||
class AzureLogAnalyticsSource(object):
|
|
||||||
def __init__(self):
|
|
||||||
self.ansible_check_mode = False
|
|
||||||
self.ansible_playbook = ""
|
|
||||||
self.ansible_version = ""
|
|
||||||
self.session = str(uuid.uuid4())
|
|
||||||
self.host = socket.gethostname()
|
|
||||||
self.user = getpass.getuser()
|
|
||||||
self.extra_vars = ""
|
|
||||||
|
|
||||||
def __build_signature(self, date, workspace_id, shared_key, content_length):
|
|
||||||
# Build authorisation signature for Azure log analytics API call
|
|
||||||
sigs = "POST\n{0}\napplication/json\nx-ms-date:{1}\n/api/logs".format(
|
|
||||||
str(content_length), date)
|
|
||||||
utf8_sigs = sigs.encode('utf-8')
|
|
||||||
decoded_shared_key = base64.b64decode(shared_key)
|
|
||||||
hmac_sha256_sigs = hmac.new(
|
|
||||||
decoded_shared_key, utf8_sigs, digestmod=hashlib.sha256).digest()
|
|
||||||
encoded_hash = base64.b64encode(hmac_sha256_sigs).decode('utf-8')
|
|
||||||
signature = "SharedKey {0}:{1}".format(workspace_id, encoded_hash)
|
|
||||||
return signature
|
|
||||||
|
|
||||||
def __build_workspace_url(self, workspace_id):
|
|
||||||
return "https://{0}.ods.opinsights.azure.com/api/logs?api-version=2016-04-01".format(workspace_id)
|
|
||||||
|
|
||||||
def __rfc1123date(self):
|
|
||||||
return datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
|
|
||||||
|
|
||||||
def send_event(self, workspace_id, shared_key, state, result, runtime):
|
|
||||||
if result._task_fields['args'].get('_ansible_check_mode') is True:
|
|
||||||
self.ansible_check_mode = True
|
|
||||||
|
|
||||||
if result._task_fields['args'].get('_ansible_version'):
|
|
||||||
self.ansible_version = \
|
|
||||||
result._task_fields['args'].get('_ansible_version')
|
|
||||||
|
|
||||||
if result._task._role:
|
|
||||||
ansible_role = str(result._task._role)
|
|
||||||
else:
|
|
||||||
ansible_role = None
|
|
||||||
|
|
||||||
data = {}
|
|
||||||
data['uuid'] = result._task._uuid
|
|
||||||
data['session'] = self.session
|
|
||||||
data['status'] = state
|
|
||||||
data['timestamp'] = self.__rfc1123date()
|
|
||||||
data['host'] = self.host
|
|
||||||
data['user'] = self.user
|
|
||||||
data['runtime'] = runtime
|
|
||||||
data['ansible_version'] = self.ansible_version
|
|
||||||
data['ansible_check_mode'] = self.ansible_check_mode
|
|
||||||
data['ansible_host'] = result._host.name
|
|
||||||
data['ansible_playbook'] = self.ansible_playbook
|
|
||||||
data['ansible_role'] = ansible_role
|
|
||||||
data['ansible_task'] = result._task_fields
|
|
||||||
# Removing args since it can contain sensitive data
|
|
||||||
if 'args' in data['ansible_task']:
|
|
||||||
data['ansible_task'].pop('args')
|
|
||||||
data['ansible_result'] = result._result
|
|
||||||
if 'content' in data['ansible_result']:
|
|
||||||
data['ansible_result'].pop('content')
|
|
||||||
|
|
||||||
# Adding extra vars info
|
|
||||||
data['extra_vars'] = self.extra_vars
|
|
||||||
|
|
||||||
# Preparing the playbook logs as JSON format and send to Azure log analytics
|
|
||||||
jsondata = json.dumps({'event': data}, cls=AnsibleJSONEncoder, sort_keys=True)
|
|
||||||
content_length = len(jsondata)
|
|
||||||
rfc1123date = self.__rfc1123date()
|
|
||||||
signature = self.__build_signature(rfc1123date, workspace_id, shared_key, content_length)
|
|
||||||
workspace_url = self.__build_workspace_url(workspace_id)
|
|
||||||
|
|
||||||
open_url(
|
|
||||||
workspace_url,
|
|
||||||
jsondata,
|
|
||||||
headers={
|
|
||||||
'content-type': 'application/json',
|
|
||||||
'Authorization': signature,
|
|
||||||
'Log-Type': 'ansible_playbook',
|
|
||||||
'x-ms-date': rfc1123date
|
|
||||||
},
|
|
||||||
method='POST'
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class CallbackModule(CallbackBase):
|
|
||||||
CALLBACK_VERSION = 2.0
|
|
||||||
CALLBACK_TYPE = 'aggregate'
|
|
||||||
CALLBACK_NAME = 'loganalytics'
|
|
||||||
CALLBACK_NEEDS_WHITELIST = True
|
|
||||||
|
|
||||||
def __init__(self, display=None):
|
|
||||||
super(CallbackModule, self).__init__(display=display)
|
|
||||||
self.start_datetimes = {} # Collect task start times
|
|
||||||
self.workspace_id = None
|
|
||||||
self.shared_key = None
|
|
||||||
self.loganalytics = AzureLogAnalyticsSource()
|
|
||||||
|
|
||||||
def _seconds_since_start(self, result):
|
|
||||||
return (
|
|
||||||
datetime.utcnow() -
|
|
||||||
self.start_datetimes[result._task._uuid]
|
|
||||||
).total_seconds()
|
|
||||||
|
|
||||||
def set_options(self, task_keys=None, var_options=None, direct=None):
|
|
||||||
super(CallbackModule, self).set_options(task_keys=task_keys, var_options=var_options, direct=direct)
|
|
||||||
self.workspace_id = self.get_option('workspace_id')
|
|
||||||
self.shared_key = self.get_option('shared_key')
|
|
||||||
|
|
||||||
def v2_playbook_on_play_start(self, play):
|
|
||||||
vm = play.get_variable_manager()
|
|
||||||
extra_vars = vm.extra_vars
|
|
||||||
self.loganalytics.extra_vars = extra_vars
|
|
||||||
|
|
||||||
def v2_playbook_on_start(self, playbook):
|
|
||||||
self.loganalytics.ansible_playbook = basename(playbook._file_name)
|
|
||||||
|
|
||||||
def v2_playbook_on_task_start(self, task, is_conditional):
|
|
||||||
self.start_datetimes[task._uuid] = datetime.utcnow()
|
|
||||||
|
|
||||||
def v2_playbook_on_handler_task_start(self, task):
|
|
||||||
self.start_datetimes[task._uuid] = datetime.utcnow()
|
|
||||||
|
|
||||||
def v2_runner_on_ok(self, result, **kwargs):
|
|
||||||
self.loganalytics.send_event(
|
|
||||||
self.workspace_id,
|
|
||||||
self.shared_key,
|
|
||||||
'OK',
|
|
||||||
result,
|
|
||||||
self._seconds_since_start(result)
|
|
||||||
)
|
|
||||||
|
|
||||||
def v2_runner_on_skipped(self, result, **kwargs):
|
|
||||||
self.loganalytics.send_event(
|
|
||||||
self.workspace_id,
|
|
||||||
self.shared_key,
|
|
||||||
'SKIPPED',
|
|
||||||
result,
|
|
||||||
self._seconds_since_start(result)
|
|
||||||
)
|
|
||||||
|
|
||||||
def v2_runner_on_failed(self, result, **kwargs):
|
|
||||||
self.loganalytics.send_event(
|
|
||||||
self.workspace_id,
|
|
||||||
self.shared_key,
|
|
||||||
'FAILED',
|
|
||||||
result,
|
|
||||||
self._seconds_since_start(result)
|
|
||||||
)
|
|
||||||
|
|
||||||
def runner_on_async_failed(self, result, **kwargs):
|
|
||||||
self.loganalytics.send_event(
|
|
||||||
self.workspace_id,
|
|
||||||
self.shared_key,
|
|
||||||
'FAILED',
|
|
||||||
result,
|
|
||||||
self._seconds_since_start(result)
|
|
||||||
)
|
|
||||||
|
|
||||||
def v2_runner_on_unreachable(self, result, **kwargs):
|
|
||||||
self.loganalytics.send_event(
|
|
||||||
self.workspace_id,
|
|
||||||
self.shared_key,
|
|
||||||
'UNREACHABLE',
|
|
||||||
result,
|
|
||||||
self._seconds_since_start(result)
|
|
||||||
)
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# (c) 2018, Samir Musali <samir.musali@logdna.com>
|
# (c) 2018, Samir Musali <samir.musali@logdna.com>
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
@@ -7,7 +6,7 @@ __metaclass__ = type
|
|||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
author: Unknown (!UNKNOWN)
|
author: Unknown (!UNKNOWN)
|
||||||
name: logdna
|
callback: logdna
|
||||||
type: aggregate
|
type: aggregate
|
||||||
short_description: Sends playbook logs to LogDNA
|
short_description: Sends playbook logs to LogDNA
|
||||||
description:
|
description:
|
||||||
@@ -78,7 +77,7 @@ def get_mac():
|
|||||||
|
|
||||||
# Getting hostname of system:
|
# Getting hostname of system:
|
||||||
def get_hostname():
|
def get_hostname():
|
||||||
return str(socket.gethostname()).split('.local', 1)[0]
|
return str(socket.gethostname()).split('.local')[0]
|
||||||
|
|
||||||
|
|
||||||
# Getting IP of system:
|
# Getting IP of system:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# (c) 2015, Logentries.com, Jimmy Tang <jimmy.tang@logentries.com>
|
# (c) 2015, Logentries.com, Jimmy Tang <jimmy.tang@logentries.com>
|
||||||
# (c) 2017 Ansible Project
|
# (c) 2017 Ansible Project
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
@@ -7,7 +6,7 @@ __metaclass__ = type
|
|||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
author: Unknown (!UNKNOWN)
|
author: Unknown (!UNKNOWN)
|
||||||
name: logentries
|
callback: logentries
|
||||||
type: notification
|
type: notification
|
||||||
short_description: Sends events to Logentries
|
short_description: Sends events to Logentries
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
# coding: utf-8 -*-
|
# (C) 2016, Ievgen Khmelenko <ujenmr@gmail.com>
|
||||||
# (C) 2020, Yevhen Khmelenko <ujenmr@gmail.com>
|
|
||||||
# (C) 2017 Ansible Project
|
# (C) 2017 Ansible Project
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = r'''
|
DOCUMENTATION = '''
|
||||||
author: Yevhen Khmelenko (@ujenmr)
|
author: Unknown (!UNKNOWN)
|
||||||
name: logstash
|
callback: logstash
|
||||||
type: notification
|
type: notification
|
||||||
short_description: Sends events to Logstash
|
short_description: Sends events to Logstash
|
||||||
description:
|
description:
|
||||||
@@ -44,62 +43,16 @@ DOCUMENTATION = r'''
|
|||||||
key: type
|
key: type
|
||||||
version_added: 1.0.0
|
version_added: 1.0.0
|
||||||
default: ansible
|
default: ansible
|
||||||
pre_command:
|
|
||||||
description: Executes command before run and result put to ansible_pre_command_output field.
|
|
||||||
version_added: 2.0.0
|
|
||||||
ini:
|
|
||||||
- section: callback_logstash
|
|
||||||
key: pre_command
|
|
||||||
env:
|
|
||||||
- name: LOGSTASH_PRE_COMMAND
|
|
||||||
format_version:
|
|
||||||
description: Logging format
|
|
||||||
type: str
|
|
||||||
version_added: 2.0.0
|
|
||||||
ini:
|
|
||||||
- section: callback_logstash
|
|
||||||
key: format_version
|
|
||||||
env:
|
|
||||||
- name: LOGSTASH_FORMAT_VERSION
|
|
||||||
default: v1
|
|
||||||
choices:
|
|
||||||
- v1
|
|
||||||
- v2
|
|
||||||
|
|
||||||
'''
|
|
||||||
|
|
||||||
EXAMPLES = r'''
|
|
||||||
ansible.cfg: |
|
|
||||||
# Enable Callback plugin
|
|
||||||
[defaults]
|
|
||||||
callback_whitelist = community.general.logstash
|
|
||||||
|
|
||||||
[callback_logstash]
|
|
||||||
server = logstash.example.com
|
|
||||||
port = 5000
|
|
||||||
pre_command = git rev-parse HEAD
|
|
||||||
type = ansible
|
|
||||||
|
|
||||||
11-input-tcp.conf: |
|
|
||||||
# Enable Logstash TCP Input
|
|
||||||
input {
|
|
||||||
tcp {
|
|
||||||
port => 5000
|
|
||||||
codec => json
|
|
||||||
add_field => { "[@metadata][beat]" => "notify" }
|
|
||||||
add_field => { "[@metadata][type]" => "ansible" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
from ansible import context
|
|
||||||
import socket
|
import socket
|
||||||
import uuid
|
import uuid
|
||||||
import logging
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import logstash
|
import logstash
|
||||||
HAS_LOGSTASH = True
|
HAS_LOGSTASH = True
|
||||||
@@ -110,78 +63,76 @@ from ansible.plugins.callback import CallbackBase
|
|||||||
|
|
||||||
|
|
||||||
class CallbackModule(CallbackBase):
|
class CallbackModule(CallbackBase):
|
||||||
|
"""
|
||||||
|
ansible logstash callback plugin
|
||||||
|
ansible.cfg:
|
||||||
|
callback_plugins = <path_to_callback_plugins_folder>
|
||||||
|
callback_whitelist = logstash
|
||||||
|
and put the plugin in <path_to_callback_plugins_folder>
|
||||||
|
|
||||||
|
logstash config:
|
||||||
|
input {
|
||||||
|
tcp {
|
||||||
|
port => 5000
|
||||||
|
codec => json
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Requires:
|
||||||
|
python-logstash
|
||||||
|
|
||||||
|
This plugin makes use of the following environment variables or ini config:
|
||||||
|
LOGSTASH_SERVER (optional): defaults to localhost
|
||||||
|
LOGSTASH_PORT (optional): defaults to 5000
|
||||||
|
LOGSTASH_TYPE (optional): defaults to ansible
|
||||||
|
"""
|
||||||
|
|
||||||
CALLBACK_VERSION = 2.0
|
CALLBACK_VERSION = 2.0
|
||||||
CALLBACK_TYPE = 'aggregate'
|
CALLBACK_TYPE = 'aggregate'
|
||||||
CALLBACK_NAME = 'community.general.logstash'
|
CALLBACK_NAME = 'community.general.logstash'
|
||||||
CALLBACK_NEEDS_WHITELIST = True
|
CALLBACK_NEEDS_WHITELIST = True
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, display=None):
|
||||||
super(CallbackModule, self).__init__()
|
super(CallbackModule, self).__init__(display=display)
|
||||||
|
|
||||||
if not HAS_LOGSTASH:
|
if not HAS_LOGSTASH:
|
||||||
self.disabled = True
|
self.disabled = True
|
||||||
self._display.warning("The required python-logstash/python3-logstash is not installed. "
|
self._display.warning("The required python-logstash is not installed. "
|
||||||
"pip install python-logstash for Python 2"
|
"pip install python-logstash")
|
||||||
"pip install python3-logstash for Python 3")
|
|
||||||
|
|
||||||
self.start_time = datetime.utcnow()
|
self.start_time = datetime.utcnow()
|
||||||
|
|
||||||
def _init_plugin(self):
|
|
||||||
if not self.disabled:
|
|
||||||
self.logger = logging.getLogger('python-logstash-logger')
|
|
||||||
self.logger.setLevel(logging.DEBUG)
|
|
||||||
|
|
||||||
self.handler = logstash.TCPLogstashHandler(
|
|
||||||
self.ls_server,
|
|
||||||
self.ls_port,
|
|
||||||
version=1,
|
|
||||||
message_type=self.ls_type
|
|
||||||
)
|
|
||||||
|
|
||||||
self.logger.addHandler(self.handler)
|
|
||||||
self.hostname = socket.gethostname()
|
|
||||||
self.session = str(uuid.uuid4())
|
|
||||||
self.errors = 0
|
|
||||||
|
|
||||||
self.base_data = {
|
|
||||||
'session': self.session,
|
|
||||||
'host': self.hostname
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.ls_pre_command is not None:
|
|
||||||
self.base_data['ansible_pre_command_output'] = os.popen(
|
|
||||||
self.ls_pre_command).read()
|
|
||||||
|
|
||||||
if context.CLIARGS is not None:
|
|
||||||
self.base_data['ansible_checkmode'] = context.CLIARGS.get('check')
|
|
||||||
self.base_data['ansible_tags'] = context.CLIARGS.get('tags')
|
|
||||||
self.base_data['ansible_skip_tags'] = context.CLIARGS.get('skip_tags')
|
|
||||||
self.base_data['inventory'] = context.CLIARGS.get('inventory')
|
|
||||||
|
|
||||||
def set_options(self, task_keys=None, var_options=None, direct=None):
|
def set_options(self, task_keys=None, var_options=None, direct=None):
|
||||||
|
|
||||||
super(CallbackModule, self).set_options(task_keys=task_keys, var_options=var_options, direct=direct)
|
super(CallbackModule, self).set_options(task_keys=task_keys, var_options=var_options, direct=direct)
|
||||||
|
|
||||||
self.ls_server = self.get_option('server')
|
self.logger = logging.getLogger('python-logstash-logger')
|
||||||
self.ls_port = int(self.get_option('port'))
|
self.logger.setLevel(logging.DEBUG)
|
||||||
self.ls_type = self.get_option('type')
|
|
||||||
self.ls_pre_command = self.get_option('pre_command')
|
|
||||||
self.ls_format_version = self.get_option('format_version')
|
|
||||||
|
|
||||||
self._init_plugin()
|
self.logstash_server = self.get_option('server')
|
||||||
|
self.logstash_port = self.get_option('port')
|
||||||
|
self.logstash_type = self.get_option('type')
|
||||||
|
self.handler = logstash.TCPLogstashHandler(
|
||||||
|
self.logstash_server,
|
||||||
|
int(self.logstash_port),
|
||||||
|
version=1,
|
||||||
|
message_type=self.logstash_type
|
||||||
|
)
|
||||||
|
self.logger.addHandler(self.handler)
|
||||||
|
self.hostname = socket.gethostname()
|
||||||
|
self.session = str(uuid.uuid1())
|
||||||
|
self.errors = 0
|
||||||
|
|
||||||
def v2_playbook_on_start(self, playbook):
|
def v2_playbook_on_start(self, playbook):
|
||||||
data = self.base_data.copy()
|
self.playbook = playbook._file_name
|
||||||
data['ansible_type'] = "start"
|
data = {
|
||||||
data['status'] = "OK"
|
'status': "OK",
|
||||||
data['ansible_playbook'] = playbook._file_name
|
'host': self.hostname,
|
||||||
|
'session': self.session,
|
||||||
if (self.ls_format_version == "v2"):
|
'ansible_type': "start",
|
||||||
self.logger.info(
|
'ansible_playbook': self.playbook,
|
||||||
"START PLAYBOOK | %s", data['ansible_playbook'], extra=data
|
}
|
||||||
)
|
self.logger.info("ansible start", extra=data)
|
||||||
else:
|
|
||||||
self.logger.info("ansible start", extra=data)
|
|
||||||
|
|
||||||
def v2_playbook_on_stats(self, stats):
|
def v2_playbook_on_stats(self, stats):
|
||||||
end_time = datetime.utcnow()
|
end_time = datetime.utcnow()
|
||||||
@@ -195,201 +146,103 @@ class CallbackModule(CallbackBase):
|
|||||||
else:
|
else:
|
||||||
status = "FAILED"
|
status = "FAILED"
|
||||||
|
|
||||||
data = self.base_data.copy()
|
data = {
|
||||||
data['ansible_type'] = "finish"
|
'status': status,
|
||||||
data['status'] = status
|
'host': self.hostname,
|
||||||
data['ansible_playbook_duration'] = runtime.total_seconds()
|
'session': self.session,
|
||||||
data['ansible_result'] = json.dumps(summarize_stat) # deprecated field
|
'ansible_type': "finish",
|
||||||
|
'ansible_playbook': self.playbook,
|
||||||
if (self.ls_format_version == "v2"):
|
'ansible_playbook_duration': runtime.total_seconds(),
|
||||||
self.logger.info(
|
'ansible_result': json.dumps(summarize_stat),
|
||||||
"FINISH PLAYBOOK | %s", json.dumps(summarize_stat), extra=data
|
}
|
||||||
)
|
self.logger.info("ansible stats", extra=data)
|
||||||
else:
|
|
||||||
self.logger.info("ansible stats", extra=data)
|
|
||||||
|
|
||||||
def v2_playbook_on_play_start(self, play):
|
|
||||||
self.play_id = str(play._uuid)
|
|
||||||
|
|
||||||
if play.name:
|
|
||||||
self.play_name = play.name
|
|
||||||
|
|
||||||
data = self.base_data.copy()
|
|
||||||
data['ansible_type'] = "start"
|
|
||||||
data['status'] = "OK"
|
|
||||||
data['ansible_play_id'] = self.play_id
|
|
||||||
data['ansible_play_name'] = self.play_name
|
|
||||||
|
|
||||||
if (self.ls_format_version == "v2"):
|
|
||||||
self.logger.info("START PLAY | %s", self.play_name, extra=data)
|
|
||||||
else:
|
|
||||||
self.logger.info("ansible play", extra=data)
|
|
||||||
|
|
||||||
def v2_playbook_on_task_start(self, task, is_conditional):
|
|
||||||
self.task_id = str(task._uuid)
|
|
||||||
|
|
||||||
'''
|
|
||||||
Tasks and handler tasks are dealt with here
|
|
||||||
'''
|
|
||||||
|
|
||||||
def v2_runner_on_ok(self, result, **kwargs):
|
def v2_runner_on_ok(self, result, **kwargs):
|
||||||
task_name = str(result._task).replace('TASK: ', '').replace('HANDLER: ', '')
|
data = {
|
||||||
|
'status': "OK",
|
||||||
data = self.base_data.copy()
|
'host': self.hostname,
|
||||||
if task_name == 'setup':
|
'session': self.session,
|
||||||
data['ansible_type'] = "setup"
|
'ansible_type': "task",
|
||||||
data['status'] = "OK"
|
'ansible_playbook': self.playbook,
|
||||||
data['ansible_host'] = result._host.name
|
'ansible_host': result._host.name,
|
||||||
data['ansible_play_id'] = self.play_id
|
'ansible_task': result._task,
|
||||||
data['ansible_play_name'] = self.play_name
|
'ansible_result': self._dump_results(result._result)
|
||||||
data['ansible_task'] = task_name
|
}
|
||||||
data['ansible_facts'] = self._dump_results(result._result)
|
self.logger.info("ansible ok", extra=data)
|
||||||
|
|
||||||
if (self.ls_format_version == "v2"):
|
|
||||||
self.logger.info(
|
|
||||||
"SETUP FACTS | %s", self._dump_results(result._result), extra=data
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
self.logger.info("ansible facts", extra=data)
|
|
||||||
else:
|
|
||||||
if 'changed' in result._result.keys():
|
|
||||||
data['ansible_changed'] = result._result['changed']
|
|
||||||
else:
|
|
||||||
data['ansible_changed'] = False
|
|
||||||
|
|
||||||
data['ansible_type'] = "task"
|
|
||||||
data['status'] = "OK"
|
|
||||||
data['ansible_host'] = result._host.name
|
|
||||||
data['ansible_play_id'] = self.play_id
|
|
||||||
data['ansible_play_name'] = self.play_name
|
|
||||||
data['ansible_task'] = task_name
|
|
||||||
data['ansible_task_id'] = self.task_id
|
|
||||||
data['ansible_result'] = self._dump_results(result._result)
|
|
||||||
|
|
||||||
if (self.ls_format_version == "v2"):
|
|
||||||
self.logger.info(
|
|
||||||
"TASK OK | %s | RESULT | %s",
|
|
||||||
task_name, self._dump_results(result._result), extra=data
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
self.logger.info("ansible ok", extra=data)
|
|
||||||
|
|
||||||
def v2_runner_on_skipped(self, result, **kwargs):
|
def v2_runner_on_skipped(self, result, **kwargs):
|
||||||
task_name = str(result._task).replace('TASK: ', '').replace('HANDLER: ', '')
|
data = {
|
||||||
|
'status': "SKIPPED",
|
||||||
data = self.base_data.copy()
|
'host': self.hostname,
|
||||||
data['ansible_type'] = "task"
|
'session': self.session,
|
||||||
data['status'] = "SKIPPED"
|
'ansible_type': "task",
|
||||||
data['ansible_host'] = result._host.name
|
'ansible_playbook': self.playbook,
|
||||||
data['ansible_play_id'] = self.play_id
|
'ansible_task': result._task,
|
||||||
data['ansible_play_name'] = self.play_name
|
'ansible_host': result._host.name
|
||||||
data['ansible_task'] = task_name
|
}
|
||||||
data['ansible_task_id'] = self.task_id
|
self.logger.info("ansible skipped", extra=data)
|
||||||
data['ansible_result'] = self._dump_results(result._result)
|
|
||||||
|
|
||||||
if (self.ls_format_version == "v2"):
|
|
||||||
self.logger.info("TASK SKIPPED | %s", task_name, extra=data)
|
|
||||||
else:
|
|
||||||
self.logger.info("ansible skipped", extra=data)
|
|
||||||
|
|
||||||
def v2_playbook_on_import_for_host(self, result, imported_file):
|
def v2_playbook_on_import_for_host(self, result, imported_file):
|
||||||
data = self.base_data.copy()
|
data = {
|
||||||
data['ansible_type'] = "import"
|
'status': "IMPORTED",
|
||||||
data['status'] = "IMPORTED"
|
'host': self.hostname,
|
||||||
data['ansible_host'] = result._host.name
|
'session': self.session,
|
||||||
data['ansible_play_id'] = self.play_id
|
'ansible_type': "import",
|
||||||
data['ansible_play_name'] = self.play_name
|
'ansible_playbook': self.playbook,
|
||||||
data['imported_file'] = imported_file
|
'ansible_host': result._host.name,
|
||||||
|
'imported_file': imported_file
|
||||||
if (self.ls_format_version == "v2"):
|
}
|
||||||
self.logger.info("IMPORT | %s", imported_file, extra=data)
|
self.logger.info("ansible import", extra=data)
|
||||||
else:
|
|
||||||
self.logger.info("ansible import", extra=data)
|
|
||||||
|
|
||||||
def v2_playbook_on_not_import_for_host(self, result, missing_file):
|
def v2_playbook_on_not_import_for_host(self, result, missing_file):
|
||||||
data = self.base_data.copy()
|
data = {
|
||||||
data['ansible_type'] = "import"
|
'status': "NOT IMPORTED",
|
||||||
data['status'] = "NOT IMPORTED"
|
'host': self.hostname,
|
||||||
data['ansible_host'] = result._host.name
|
'session': self.session,
|
||||||
data['ansible_play_id'] = self.play_id
|
'ansible_type': "import",
|
||||||
data['ansible_play_name'] = self.play_name
|
'ansible_playbook': self.playbook,
|
||||||
data['imported_file'] = missing_file
|
'ansible_host': result._host.name,
|
||||||
|
'missing_file': missing_file
|
||||||
if (self.ls_format_version == "v2"):
|
}
|
||||||
self.logger.info("NOT IMPORTED | %s", missing_file, extra=data)
|
self.logger.info("ansible import", extra=data)
|
||||||
else:
|
|
||||||
self.logger.info("ansible import", extra=data)
|
|
||||||
|
|
||||||
def v2_runner_on_failed(self, result, **kwargs):
|
def v2_runner_on_failed(self, result, **kwargs):
|
||||||
task_name = str(result._task).replace('TASK: ', '').replace('HANDLER: ', '')
|
data = {
|
||||||
|
'status': "FAILED",
|
||||||
data = self.base_data.copy()
|
'host': self.hostname,
|
||||||
if 'changed' in result._result.keys():
|
'session': self.session,
|
||||||
data['ansible_changed'] = result._result['changed']
|
'ansible_type': "task",
|
||||||
else:
|
'ansible_playbook': self.playbook,
|
||||||
data['ansible_changed'] = False
|
'ansible_host': result._host.name,
|
||||||
|
'ansible_task': result._task,
|
||||||
data['ansible_type'] = "task"
|
'ansible_result': self._dump_results(result._result)
|
||||||
data['status'] = "FAILED"
|
}
|
||||||
data['ansible_host'] = result._host.name
|
|
||||||
data['ansible_play_id'] = self.play_id
|
|
||||||
data['ansible_play_name'] = self.play_name
|
|
||||||
data['ansible_task'] = task_name
|
|
||||||
data['ansible_task_id'] = self.task_id
|
|
||||||
data['ansible_result'] = self._dump_results(result._result)
|
|
||||||
|
|
||||||
self.errors += 1
|
self.errors += 1
|
||||||
if (self.ls_format_version == "v2"):
|
self.logger.error("ansible failed", extra=data)
|
||||||
self.logger.error(
|
|
||||||
"TASK FAILED | %s | HOST | %s | RESULT | %s",
|
|
||||||
task_name, self.hostname,
|
|
||||||
self._dump_results(result._result), extra=data
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
self.logger.error("ansible failed", extra=data)
|
|
||||||
|
|
||||||
def v2_runner_on_unreachable(self, result, **kwargs):
|
def v2_runner_on_unreachable(self, result, **kwargs):
|
||||||
task_name = str(result._task).replace('TASK: ', '').replace('HANDLER: ', '')
|
data = {
|
||||||
|
'status': "UNREACHABLE",
|
||||||
data = self.base_data.copy()
|
'host': self.hostname,
|
||||||
data['ansible_type'] = "task"
|
'session': self.session,
|
||||||
data['status'] = "UNREACHABLE"
|
'ansible_type': "task",
|
||||||
data['ansible_host'] = result._host.name
|
'ansible_playbook': self.playbook,
|
||||||
data['ansible_play_id'] = self.play_id
|
'ansible_host': result._host.name,
|
||||||
data['ansible_play_name'] = self.play_name
|
'ansible_task': result._task,
|
||||||
data['ansible_task'] = task_name
|
'ansible_result': self._dump_results(result._result)
|
||||||
data['ansible_task_id'] = self.task_id
|
}
|
||||||
data['ansible_result'] = self._dump_results(result._result)
|
self.logger.error("ansible unreachable", extra=data)
|
||||||
|
|
||||||
self.errors += 1
|
|
||||||
if (self.ls_format_version == "v2"):
|
|
||||||
self.logger.error(
|
|
||||||
"UNREACHABLE | %s | HOST | %s | RESULT | %s",
|
|
||||||
task_name, self.hostname,
|
|
||||||
self._dump_results(result._result), extra=data
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
self.logger.error("ansible unreachable", extra=data)
|
|
||||||
|
|
||||||
def v2_runner_on_async_failed(self, result, **kwargs):
|
def v2_runner_on_async_failed(self, result, **kwargs):
|
||||||
task_name = str(result._task).replace('TASK: ', '').replace('HANDLER: ', '')
|
data = {
|
||||||
|
'status': "FAILED",
|
||||||
data = self.base_data.copy()
|
'host': self.hostname,
|
||||||
data['ansible_type'] = "task"
|
'session': self.session,
|
||||||
data['status'] = "FAILED"
|
'ansible_type': "task",
|
||||||
data['ansible_host'] = result._host.name
|
'ansible_playbook': self.playbook,
|
||||||
data['ansible_play_id'] = self.play_id
|
'ansible_host': result._host.name,
|
||||||
data['ansible_play_name'] = self.play_name
|
'ansible_task': result._task,
|
||||||
data['ansible_task'] = task_name
|
'ansible_result': self._dump_results(result._result)
|
||||||
data['ansible_task_id'] = self.task_id
|
}
|
||||||
data['ansible_result'] = self._dump_results(result._result)
|
|
||||||
|
|
||||||
self.errors += 1
|
self.errors += 1
|
||||||
if (self.ls_format_version == "v2"):
|
self.logger.error("ansible async", extra=data)
|
||||||
self.logger.error(
|
|
||||||
"ASYNC FAILED | %s | HOST | %s | RESULT | %s",
|
|
||||||
task_name, self.hostname,
|
|
||||||
self._dump_results(result._result), extra=data
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
self.logger.error("ansible async", extra=data)
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from __future__ import (absolute_import, division, print_function)
|
|||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
name: mail
|
callback: mail
|
||||||
type: notification
|
type: notification
|
||||||
short_description: Sends failure events via email
|
short_description: Sends failure events via email
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from __future__ import (absolute_import, division, print_function)
|
|||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
name: nrdp
|
callback: nrdp
|
||||||
type: notification
|
type: notification
|
||||||
author: "Remi VERCHERE (@rverchere)"
|
author: "Remi VERCHERE (@rverchere)"
|
||||||
short_description: post task result to a nagios server through nrdp
|
short_description: post task result to a nagios server through nrdp
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# (c) 2017 Ansible Project
|
# (c) 2017 Ansible Project
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
@@ -8,7 +7,7 @@ __metaclass__ = type
|
|||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
author: Unknown (!UNKNOWN)
|
author: Unknown (!UNKNOWN)
|
||||||
name: 'null'
|
callback: 'null'
|
||||||
type: stdout
|
type: stdout
|
||||||
requirements:
|
requirements:
|
||||||
- set as main display callback
|
- set as main display callback
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# (c) 2012, Michael DeHaan, <michael.dehaan@gmail.com>
|
# (c) 2012, Michael DeHaan, <michael.dehaan@gmail.com>
|
||||||
# (c) 2017 Ansible Project
|
# (c) 2017 Ansible Project
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
@@ -9,7 +8,7 @@ __metaclass__ = type
|
|||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
author: Unknown (!UNKNOWN)
|
author: Unknown (!UNKNOWN)
|
||||||
name: say
|
callback: say
|
||||||
type: notification
|
type: notification
|
||||||
requirements:
|
requirements:
|
||||||
- whitelisting in configuration
|
- whitelisting in configuration
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# (c) Fastly, inc 2016
|
# (c) Fastly, inc 2016
|
||||||
# (c) 2017 Ansible Project
|
# (c) 2017 Ansible Project
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
@@ -8,7 +7,7 @@ __metaclass__ = type
|
|||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
author: Unknown (!UNKNOWN)
|
author: Unknown (!UNKNOWN)
|
||||||
name: selective
|
callback: selective
|
||||||
type: stdout
|
type: stdout
|
||||||
requirements:
|
requirements:
|
||||||
- set as main display callback
|
- set as main display callback
|
||||||
@@ -42,16 +41,7 @@ import difflib
|
|||||||
from ansible import constants as C
|
from ansible import constants as C
|
||||||
from ansible.plugins.callback import CallbackBase
|
from ansible.plugins.callback import CallbackBase
|
||||||
from ansible.module_utils._text import to_text
|
from ansible.module_utils._text import to_text
|
||||||
|
from ansible.utils.color import codeCodes
|
||||||
try:
|
|
||||||
codeCodes = C.COLOR_CODES
|
|
||||||
except AttributeError:
|
|
||||||
# This constant was moved to ansible.constants in
|
|
||||||
# https://github.com/ansible/ansible/commit/1202dd000f10b0e8959019484f1c3b3f9628fc67
|
|
||||||
# (will be included in ansible-core 2.11.0). For older Ansible/ansible-base versions,
|
|
||||||
# we include from the original location.
|
|
||||||
from ansible.utils.color import codeCodes
|
|
||||||
|
|
||||||
|
|
||||||
DONT_COLORIZE = False
|
DONT_COLORIZE = False
|
||||||
COLORS = {
|
COLORS = {
|
||||||
@@ -68,7 +58,7 @@ COLORS = {
|
|||||||
|
|
||||||
def dict_diff(prv, nxt):
|
def dict_diff(prv, nxt):
|
||||||
"""Return a dict of keys that differ with another config object."""
|
"""Return a dict of keys that differ with another config object."""
|
||||||
keys = set(list(prv.keys()) + list(nxt.keys()))
|
keys = set(prv.keys() + nxt.keys())
|
||||||
result = {}
|
result = {}
|
||||||
for k in keys:
|
for k in keys:
|
||||||
if prv.get(k) != nxt.get(k):
|
if prv.get(k) != nxt.get(k):
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# (C) 2014-2015, Matt Martz <matt@sivel.net>
|
# (C) 2014-2015, Matt Martz <matt@sivel.net>
|
||||||
# (C) 2017 Ansible Project
|
# (C) 2017 Ansible Project
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
@@ -9,7 +8,7 @@ __metaclass__ = type
|
|||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
author: Unknown (!UNKNOWN)
|
author: Unknown (!UNKNOWN)
|
||||||
name: slack
|
callback: slack
|
||||||
type: notification
|
type: notification
|
||||||
requirements:
|
requirements:
|
||||||
- whitelist in configuration
|
- whitelist in configuration
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ from __future__ import (absolute_import, division, print_function)
|
|||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
name: splunk
|
callback: splunk
|
||||||
type: aggregate
|
type: aggregate
|
||||||
short_description: Sends task result events to Splunk HTTP Event Collector
|
short_description: Sends task result events to Splunk HTTP Event Collector
|
||||||
author: "Stuart Hirst (!UNKNOWN) <support@convergingdata.com>"
|
author: "Stuart Hirst (!UNKNOWN) <support@convergingdata.com>"
|
||||||
@@ -57,17 +57,6 @@ DOCUMENTATION = '''
|
|||||||
type: bool
|
type: bool
|
||||||
default: true
|
default: true
|
||||||
version_added: '1.0.0'
|
version_added: '1.0.0'
|
||||||
include_milliseconds:
|
|
||||||
description: Whether to include milliseconds as part of the generated timestamp field in the event
|
|
||||||
sent to the Splunk HTTP collector
|
|
||||||
env:
|
|
||||||
- name: SPLUNK_INCLUDE_MILLISECONDS
|
|
||||||
ini:
|
|
||||||
- section: callback_splunk
|
|
||||||
key: include_milliseconds
|
|
||||||
type: bool
|
|
||||||
default: false
|
|
||||||
version_added: 2.0.0
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = '''
|
EXAMPLES = '''
|
||||||
@@ -107,7 +96,7 @@ class SplunkHTTPCollectorSource(object):
|
|||||||
self.ip_address = socket.gethostbyname(socket.gethostname())
|
self.ip_address = socket.gethostbyname(socket.gethostname())
|
||||||
self.user = getpass.getuser()
|
self.user = getpass.getuser()
|
||||||
|
|
||||||
def send_event(self, url, authtoken, validate_certs, include_milliseconds, state, result, runtime):
|
def send_event(self, url, authtoken, validate_certs, state, result, runtime):
|
||||||
if result._task_fields['args'].get('_ansible_check_mode') is True:
|
if result._task_fields['args'].get('_ansible_check_mode') is True:
|
||||||
self.ansible_check_mode = True
|
self.ansible_check_mode = True
|
||||||
|
|
||||||
@@ -127,13 +116,8 @@ class SplunkHTTPCollectorSource(object):
|
|||||||
data['uuid'] = result._task._uuid
|
data['uuid'] = result._task._uuid
|
||||||
data['session'] = self.session
|
data['session'] = self.session
|
||||||
data['status'] = state
|
data['status'] = state
|
||||||
|
data['timestamp'] = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S '
|
||||||
if include_milliseconds:
|
'+0000')
|
||||||
time_format = '%Y-%m-%d %H:%M:%S.%f +0000'
|
|
||||||
else:
|
|
||||||
time_format = '%Y-%m-%d %H:%M:%S +0000'
|
|
||||||
|
|
||||||
data['timestamp'] = datetime.utcnow().strftime(time_format)
|
|
||||||
data['host'] = self.host
|
data['host'] = self.host
|
||||||
data['ip_address'] = self.ip_address
|
data['ip_address'] = self.ip_address
|
||||||
data['user'] = self.user
|
data['user'] = self.user
|
||||||
@@ -174,7 +158,6 @@ class CallbackModule(CallbackBase):
|
|||||||
self.url = None
|
self.url = None
|
||||||
self.authtoken = None
|
self.authtoken = None
|
||||||
self.validate_certs = None
|
self.validate_certs = None
|
||||||
self.include_milliseconds = None
|
|
||||||
self.splunk = SplunkHTTPCollectorSource()
|
self.splunk = SplunkHTTPCollectorSource()
|
||||||
|
|
||||||
def _runtime(self, result):
|
def _runtime(self, result):
|
||||||
@@ -210,8 +193,6 @@ class CallbackModule(CallbackBase):
|
|||||||
|
|
||||||
self.validate_certs = self.get_option('validate_certs')
|
self.validate_certs = self.get_option('validate_certs')
|
||||||
|
|
||||||
self.include_milliseconds = self.get_option('include_milliseconds')
|
|
||||||
|
|
||||||
def v2_playbook_on_start(self, playbook):
|
def v2_playbook_on_start(self, playbook):
|
||||||
self.splunk.ansible_playbook = basename(playbook._file_name)
|
self.splunk.ansible_playbook = basename(playbook._file_name)
|
||||||
|
|
||||||
@@ -226,7 +207,6 @@ class CallbackModule(CallbackBase):
|
|||||||
self.url,
|
self.url,
|
||||||
self.authtoken,
|
self.authtoken,
|
||||||
self.validate_certs,
|
self.validate_certs,
|
||||||
self.include_milliseconds,
|
|
||||||
'OK',
|
'OK',
|
||||||
result,
|
result,
|
||||||
self._runtime(result)
|
self._runtime(result)
|
||||||
@@ -237,7 +217,6 @@ class CallbackModule(CallbackBase):
|
|||||||
self.url,
|
self.url,
|
||||||
self.authtoken,
|
self.authtoken,
|
||||||
self.validate_certs,
|
self.validate_certs,
|
||||||
self.include_milliseconds,
|
|
||||||
'SKIPPED',
|
'SKIPPED',
|
||||||
result,
|
result,
|
||||||
self._runtime(result)
|
self._runtime(result)
|
||||||
@@ -248,7 +227,6 @@ class CallbackModule(CallbackBase):
|
|||||||
self.url,
|
self.url,
|
||||||
self.authtoken,
|
self.authtoken,
|
||||||
self.validate_certs,
|
self.validate_certs,
|
||||||
self.include_milliseconds,
|
|
||||||
'FAILED',
|
'FAILED',
|
||||||
result,
|
result,
|
||||||
self._runtime(result)
|
self._runtime(result)
|
||||||
@@ -259,7 +237,6 @@ class CallbackModule(CallbackBase):
|
|||||||
self.url,
|
self.url,
|
||||||
self.authtoken,
|
self.authtoken,
|
||||||
self.validate_certs,
|
self.validate_certs,
|
||||||
self.include_milliseconds,
|
|
||||||
'FAILED',
|
'FAILED',
|
||||||
result,
|
result,
|
||||||
self._runtime(result)
|
self._runtime(result)
|
||||||
@@ -270,7 +247,6 @@ class CallbackModule(CallbackBase):
|
|||||||
self.url,
|
self.url,
|
||||||
self.authtoken,
|
self.authtoken,
|
||||||
self.validate_certs,
|
self.validate_certs,
|
||||||
self.include_milliseconds,
|
|
||||||
'UNREACHABLE',
|
'UNREACHABLE',
|
||||||
result,
|
result,
|
||||||
self._runtime(result)
|
self._runtime(result)
|
||||||
|
|||||||
71
plugins/callback/stderr.py
Normal file
71
plugins/callback/stderr.py
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
# (c) 2017, Frederic Van Espen <github@freh.be>
|
||||||
|
# (c) 2017 Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
# Make coding more python3-ish
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
DOCUMENTATION = '''
|
||||||
|
author: Unknown (!UNKNOWN)
|
||||||
|
callback: stderr
|
||||||
|
type: stdout
|
||||||
|
requirements:
|
||||||
|
- set as main display callback
|
||||||
|
short_description: Splits output, sending failed tasks to stderr
|
||||||
|
deprecated:
|
||||||
|
why: The 'default' callback plugin now supports this functionality
|
||||||
|
removed_in: '2.0.0' # was Ansible 2.11
|
||||||
|
alternative: "'default' callback plugin with 'display_failed_stderr = yes' option"
|
||||||
|
extends_documentation_fragment:
|
||||||
|
- default_callback
|
||||||
|
description:
|
||||||
|
- This is the stderr callback plugin, it behaves like the default callback plugin but sends error output to stderr.
|
||||||
|
- Also it does not output skipped host/task/item status
|
||||||
|
'''
|
||||||
|
|
||||||
|
from ansible import constants as C
|
||||||
|
from ansible.plugins.callback.default import CallbackModule as CallbackModule_default
|
||||||
|
|
||||||
|
|
||||||
|
class CallbackModule(CallbackModule_default):
|
||||||
|
|
||||||
|
'''
|
||||||
|
This is the stderr callback plugin, which reuses the default
|
||||||
|
callback plugin but sends error output to stderr.
|
||||||
|
'''
|
||||||
|
|
||||||
|
CALLBACK_VERSION = 2.0
|
||||||
|
CALLBACK_TYPE = 'stdout'
|
||||||
|
CALLBACK_NAME = 'community.general.stderr'
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
|
||||||
|
self.super_ref = super(CallbackModule, self)
|
||||||
|
self.super_ref.__init__()
|
||||||
|
|
||||||
|
def v2_runner_on_failed(self, result, ignore_errors=False):
|
||||||
|
|
||||||
|
delegated_vars = result._result.get('_ansible_delegated_vars', None)
|
||||||
|
self._clean_results(result._result, result._task.action)
|
||||||
|
|
||||||
|
if self._play.strategy == 'free' and self._last_task_banner != result._task._uuid:
|
||||||
|
self._print_task_banner(result._task)
|
||||||
|
|
||||||
|
self._handle_exception(result._result, use_stderr=True)
|
||||||
|
self._handle_warnings(result._result)
|
||||||
|
|
||||||
|
if result._task.loop and 'results' in result._result:
|
||||||
|
self._process_items(result)
|
||||||
|
|
||||||
|
else:
|
||||||
|
if delegated_vars:
|
||||||
|
self._display.display("fatal: [%s -> %s]: FAILED! => %s" % (result._host.get_name(), delegated_vars['ansible_host'],
|
||||||
|
self._dump_results(result._result)), color=C.COLOR_ERROR,
|
||||||
|
stderr=True)
|
||||||
|
else:
|
||||||
|
self._display.display("fatal: [%s]: FAILED! => %s" % (result._host.get_name(), self._dump_results(result._result)),
|
||||||
|
color=C.COLOR_ERROR, stderr=True)
|
||||||
|
|
||||||
|
if ignore_errors:
|
||||||
|
self._display.display("...ignoring", color=C.COLOR_SKIP)
|
||||||
@@ -18,7 +18,7 @@ from __future__ import (absolute_import, division, print_function)
|
|||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
name: sumologic
|
callback: sumologic
|
||||||
type: aggregate
|
type: aggregate
|
||||||
short_description: Sends task result events to Sumologic
|
short_description: Sends task result events to Sumologic
|
||||||
author: "Ryan Currah (@ryancurrah)"
|
author: "Ryan Currah (@ryancurrah)"
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# (c) 2017 Ansible Project
|
# (c) 2017 Ansible Project
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
@@ -8,7 +7,7 @@ __metaclass__ = type
|
|||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
author: Unknown (!UNKNOWN)
|
author: Unknown (!UNKNOWN)
|
||||||
name: syslog_json
|
callback: syslog_json
|
||||||
type: notification
|
type: notification
|
||||||
requirements:
|
requirements:
|
||||||
- whitelist in configuration
|
- whitelist in configuration
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# Copyright: (c) 2017, Allyson Bowles <@akatch>
|
# Copyright: (c) 2017, Allyson Bowles <@akatch>
|
||||||
# Copyright: (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com>
|
# Copyright: (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com>
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
@@ -8,7 +7,7 @@ from __future__ import (absolute_import, division, print_function)
|
|||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
name: unixy
|
callback: unixy
|
||||||
type: stdout
|
type: stdout
|
||||||
author: Allyson Bowles (@akatch)
|
author: Allyson Bowles (@akatch)
|
||||||
short_description: condensed Ansible output
|
short_description: condensed Ansible output
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# (c) 2017 Ansible Project
|
# (c) 2017 Ansible Project
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
@@ -8,7 +7,7 @@ __metaclass__ = type
|
|||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
author: Unknown (!UNKNOWN)
|
author: Unknown (!UNKNOWN)
|
||||||
name: yaml
|
callback: yaml
|
||||||
type: stdout
|
type: stdout
|
||||||
short_description: yaml-ized Ansible screen output
|
short_description: yaml-ized Ansible screen output
|
||||||
description:
|
description:
|
||||||
@@ -42,29 +41,28 @@ def should_use_block(value):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
class MyDumper(AnsibleDumper):
|
def my_represent_scalar(self, tag, value, style=None):
|
||||||
def represent_scalar(self, tag, value, style=None):
|
"""Uses block style for multi-line strings"""
|
||||||
"""Uses block style for multi-line strings"""
|
if style is None:
|
||||||
if style is None:
|
if should_use_block(value):
|
||||||
if should_use_block(value):
|
style = '|'
|
||||||
style = '|'
|
# we care more about readable than accuracy, so...
|
||||||
# we care more about readable than accuracy, so...
|
# ...no trailing space
|
||||||
# ...no trailing space
|
value = value.rstrip()
|
||||||
value = value.rstrip()
|
# ...and non-printable characters
|
||||||
# ...and non-printable characters
|
value = ''.join(x for x in value if x in string.printable or ord(x) >= 0xA0)
|
||||||
value = ''.join(x for x in value if x in string.printable or ord(x) >= 0xA0)
|
# ...tabs prevent blocks from expanding
|
||||||
# ...tabs prevent blocks from expanding
|
value = value.expandtabs()
|
||||||
value = value.expandtabs()
|
# ...and odd bits of whitespace
|
||||||
# ...and odd bits of whitespace
|
value = re.sub(r'[\x0b\x0c\r]', '', value)
|
||||||
value = re.sub(r'[\x0b\x0c\r]', '', value)
|
# ...as does trailing space
|
||||||
# ...as does trailing space
|
value = re.sub(r' +\n', '\n', value)
|
||||||
value = re.sub(r' +\n', '\n', value)
|
else:
|
||||||
else:
|
style = self.default_style
|
||||||
style = self.default_style
|
node = yaml.representer.ScalarNode(tag, value, style=style)
|
||||||
node = yaml.representer.ScalarNode(tag, value, style=style)
|
if self.alias_key is not None:
|
||||||
if self.alias_key is not None:
|
self.represented_objects[self.alias_key] = node
|
||||||
self.represented_objects[self.alias_key] = node
|
return node
|
||||||
return node
|
|
||||||
|
|
||||||
|
|
||||||
class CallbackModule(Default):
|
class CallbackModule(Default):
|
||||||
@@ -80,6 +78,7 @@ class CallbackModule(Default):
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(CallbackModule, self).__init__()
|
super(CallbackModule, self).__init__()
|
||||||
|
yaml.representer.BaseRepresenter.represent_scalar = my_represent_scalar
|
||||||
|
|
||||||
def _dump_results(self, result, indent=None, sort_keys=True, keep_invocation=False):
|
def _dump_results(self, result, indent=None, sort_keys=True, keep_invocation=False):
|
||||||
if result.get('_ansible_no_log', False):
|
if result.get('_ansible_no_log', False):
|
||||||
@@ -121,7 +120,7 @@ class CallbackModule(Default):
|
|||||||
|
|
||||||
if abridged_result:
|
if abridged_result:
|
||||||
dumped += '\n'
|
dumped += '\n'
|
||||||
dumped += to_text(yaml.dump(abridged_result, allow_unicode=True, width=1000, Dumper=MyDumper, default_flow_style=False))
|
dumped += to_text(yaml.dump(abridged_result, allow_unicode=True, width=1000, Dumper=AnsibleDumper, default_flow_style=False))
|
||||||
|
|
||||||
# indent by a couple of spaces
|
# indent by a couple of spaces
|
||||||
dumped = '\n '.join(dumped.split('\n')).rstrip()
|
dumped = '\n '.join(dumped.split('\n')).rstrip()
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# Based on local.py (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
|
# Based on local.py (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
|
||||||
#
|
#
|
||||||
# (c) 2013, Maykel Moya <mmoya@speedyrails.com>
|
# (c) 2013, Maykel Moya <mmoya@speedyrails.com>
|
||||||
@@ -11,7 +10,7 @@ __metaclass__ = type
|
|||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
author: Maykel Moya (!UNKNOWN) <mmoya@speedyrails.com>
|
author: Maykel Moya (!UNKNOWN) <mmoya@speedyrails.com>
|
||||||
name: chroot
|
connection: chroot
|
||||||
short_description: Interact with local chroot
|
short_description: Interact with local chroot
|
||||||
description:
|
description:
|
||||||
- Run commands or put/fetch files to an existing chroot on the Ansible controller.
|
- Run commands or put/fetch files to an existing chroot on the Ansible controller.
|
||||||
|
|||||||
364
plugins/connection/docker.py
Normal file
364
plugins/connection/docker.py
Normal file
@@ -0,0 +1,364 @@
|
|||||||
|
# Based on the chroot connection plugin by Maykel Moya
|
||||||
|
#
|
||||||
|
# (c) 2014, Lorin Hochstein
|
||||||
|
# (c) 2015, Leendert Brouwer (https://github.com/objectified)
|
||||||
|
# (c) 2015, Toshio Kuratomi <tkuratomi@ansible.com>
|
||||||
|
# Copyright (c) 2017 Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
DOCUMENTATION = '''
|
||||||
|
author:
|
||||||
|
- Lorin Hochestein (!UNKNOWN)
|
||||||
|
- Leendert Brouwer (!UNKNOWN)
|
||||||
|
connection: docker
|
||||||
|
short_description: Run tasks in docker containers
|
||||||
|
description:
|
||||||
|
- Run commands or put/fetch files to an existing docker container.
|
||||||
|
options:
|
||||||
|
remote_user:
|
||||||
|
description:
|
||||||
|
- The user to execute as inside the container
|
||||||
|
vars:
|
||||||
|
- name: ansible_user
|
||||||
|
- name: ansible_docker_user
|
||||||
|
docker_extra_args:
|
||||||
|
description:
|
||||||
|
- Extra arguments to pass to the docker command line
|
||||||
|
default: ''
|
||||||
|
remote_addr:
|
||||||
|
description:
|
||||||
|
- The name of the container you want to access.
|
||||||
|
default: inventory_hostname
|
||||||
|
vars:
|
||||||
|
- name: ansible_host
|
||||||
|
- name: ansible_docker_host
|
||||||
|
'''
|
||||||
|
|
||||||
|
import distutils.spawn
|
||||||
|
import fcntl
|
||||||
|
import os
|
||||||
|
import os.path
|
||||||
|
import subprocess
|
||||||
|
import re
|
||||||
|
|
||||||
|
from distutils.version import LooseVersion
|
||||||
|
|
||||||
|
import ansible.constants as C
|
||||||
|
from ansible.compat import selectors
|
||||||
|
from ansible.errors import AnsibleError, AnsibleFileNotFound
|
||||||
|
from ansible.module_utils.six.moves import shlex_quote
|
||||||
|
from ansible.module_utils._text import to_bytes, to_native, to_text
|
||||||
|
from ansible.plugins.connection import ConnectionBase, BUFSIZE
|
||||||
|
from ansible.utils.display import Display
|
||||||
|
|
||||||
|
display = Display()
|
||||||
|
|
||||||
|
|
||||||
|
class Connection(ConnectionBase):
|
||||||
|
''' Local docker based connections '''
|
||||||
|
|
||||||
|
transport = 'community.general.docker'
|
||||||
|
has_pipelining = True
|
||||||
|
|
||||||
|
def __init__(self, play_context, new_stdin, *args, **kwargs):
|
||||||
|
super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs)
|
||||||
|
|
||||||
|
# Note: docker supports running as non-root in some configurations.
|
||||||
|
# (For instance, setting the UNIX socket file to be readable and
|
||||||
|
# writable by a specific UNIX group and then putting users into that
|
||||||
|
# group). Therefore we don't check that the user is root when using
|
||||||
|
# this connection. But if the user is getting a permission denied
|
||||||
|
# error it probably means that docker on their system is only
|
||||||
|
# configured to be connected to by root and they are not running as
|
||||||
|
# root.
|
||||||
|
|
||||||
|
# Windows uses Powershell modules
|
||||||
|
if getattr(self._shell, "_IS_WINDOWS", False):
|
||||||
|
self.module_implementation_preferences = ('.ps1', '.exe', '')
|
||||||
|
|
||||||
|
if 'docker_command' in kwargs:
|
||||||
|
self.docker_cmd = kwargs['docker_command']
|
||||||
|
else:
|
||||||
|
self.docker_cmd = distutils.spawn.find_executable('docker')
|
||||||
|
if not self.docker_cmd:
|
||||||
|
raise AnsibleError("docker command not found in PATH")
|
||||||
|
|
||||||
|
docker_version = self._get_docker_version()
|
||||||
|
if docker_version == u'dev':
|
||||||
|
display.warning(u'Docker version number is "dev". Will assume latest version.')
|
||||||
|
if docker_version != u'dev' and LooseVersion(docker_version) < LooseVersion(u'1.3'):
|
||||||
|
raise AnsibleError('docker connection type requires docker 1.3 or higher')
|
||||||
|
|
||||||
|
# The remote user we will request from docker (if supported)
|
||||||
|
self.remote_user = None
|
||||||
|
# The actual user which will execute commands in docker (if known)
|
||||||
|
self.actual_user = None
|
||||||
|
|
||||||
|
if self._play_context.remote_user is not None:
|
||||||
|
if docker_version == u'dev' or LooseVersion(docker_version) >= LooseVersion(u'1.7'):
|
||||||
|
# Support for specifying the exec user was added in docker 1.7
|
||||||
|
self.remote_user = self._play_context.remote_user
|
||||||
|
self.actual_user = self.remote_user
|
||||||
|
else:
|
||||||
|
self.actual_user = self._get_docker_remote_user()
|
||||||
|
|
||||||
|
if self.actual_user != self._play_context.remote_user:
|
||||||
|
display.warning(u'docker {0} does not support remote_user, using container default: {1}'
|
||||||
|
.format(docker_version, self.actual_user or u'?'))
|
||||||
|
elif self._display.verbosity > 2:
|
||||||
|
# Since we're not setting the actual_user, look it up so we have it for logging later
|
||||||
|
# Only do this if display verbosity is high enough that we'll need the value
|
||||||
|
# This saves overhead from calling into docker when we don't need to
|
||||||
|
self.actual_user = self._get_docker_remote_user()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _sanitize_version(version):
|
||||||
|
return re.sub(u'[^0-9a-zA-Z.]', u'', version)
|
||||||
|
|
||||||
|
def _old_docker_version(self):
|
||||||
|
cmd_args = []
|
||||||
|
if self._play_context.docker_extra_args:
|
||||||
|
cmd_args += self._play_context.docker_extra_args.split(' ')
|
||||||
|
|
||||||
|
old_version_subcommand = ['version']
|
||||||
|
|
||||||
|
old_docker_cmd = [self.docker_cmd] + cmd_args + old_version_subcommand
|
||||||
|
p = subprocess.Popen(old_docker_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
cmd_output, err = p.communicate()
|
||||||
|
|
||||||
|
return old_docker_cmd, to_native(cmd_output), err, p.returncode
|
||||||
|
|
||||||
|
def _new_docker_version(self):
|
||||||
|
# no result yet, must be newer Docker version
|
||||||
|
cmd_args = []
|
||||||
|
if self._play_context.docker_extra_args:
|
||||||
|
cmd_args += self._play_context.docker_extra_args.split(' ')
|
||||||
|
|
||||||
|
new_version_subcommand = ['version', '--format', "'{{.Server.Version}}'"]
|
||||||
|
|
||||||
|
new_docker_cmd = [self.docker_cmd] + cmd_args + new_version_subcommand
|
||||||
|
p = subprocess.Popen(new_docker_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
cmd_output, err = p.communicate()
|
||||||
|
return new_docker_cmd, to_native(cmd_output), err, p.returncode
|
||||||
|
|
||||||
|
def _get_docker_version(self):
|
||||||
|
|
||||||
|
cmd, cmd_output, err, returncode = self._old_docker_version()
|
||||||
|
if returncode == 0:
|
||||||
|
for line in to_text(cmd_output, errors='surrogate_or_strict').split(u'\n'):
|
||||||
|
if line.startswith(u'Server version:'): # old docker versions
|
||||||
|
return self._sanitize_version(line.split()[2])
|
||||||
|
|
||||||
|
cmd, cmd_output, err, returncode = self._new_docker_version()
|
||||||
|
if returncode:
|
||||||
|
raise AnsibleError('Docker version check (%s) failed: %s' % (to_native(cmd), to_native(err)))
|
||||||
|
|
||||||
|
return self._sanitize_version(to_text(cmd_output, errors='surrogate_or_strict'))
|
||||||
|
|
||||||
|
def _get_docker_remote_user(self):
|
||||||
|
""" Get the default user configured in the docker container """
|
||||||
|
p = subprocess.Popen([self.docker_cmd, 'inspect', '--format', '{{.Config.User}}', self._play_context.remote_addr],
|
||||||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
|
||||||
|
out, err = p.communicate()
|
||||||
|
out = to_text(out, errors='surrogate_or_strict')
|
||||||
|
|
||||||
|
if p.returncode != 0:
|
||||||
|
display.warning(u'unable to retrieve default user from docker container: %s %s' % (out, to_text(err)))
|
||||||
|
return None
|
||||||
|
|
||||||
|
# The default exec user is root, unless it was changed in the Dockerfile with USER
|
||||||
|
return out.strip() or u'root'
|
||||||
|
|
||||||
|
def _build_exec_cmd(self, cmd):
|
||||||
|
""" Build the local docker exec command to run cmd on remote_host
|
||||||
|
|
||||||
|
If remote_user is available and is supported by the docker
|
||||||
|
version we are using, it will be provided to docker exec.
|
||||||
|
"""
|
||||||
|
|
||||||
|
local_cmd = [self.docker_cmd]
|
||||||
|
|
||||||
|
if self._play_context.docker_extra_args:
|
||||||
|
local_cmd += self._play_context.docker_extra_args.split(' ')
|
||||||
|
|
||||||
|
local_cmd += [b'exec']
|
||||||
|
|
||||||
|
if self.remote_user is not None:
|
||||||
|
local_cmd += [b'-u', self.remote_user]
|
||||||
|
|
||||||
|
# -i is needed to keep stdin open which allows pipelining to work
|
||||||
|
local_cmd += [b'-i', self._play_context.remote_addr] + cmd
|
||||||
|
|
||||||
|
return local_cmd
|
||||||
|
|
||||||
|
def _connect(self, port=None):
|
||||||
|
""" Connect to the container. Nothing to do """
|
||||||
|
super(Connection, self)._connect()
|
||||||
|
if not self._connected:
|
||||||
|
display.vvv(u"ESTABLISH DOCKER CONNECTION FOR USER: {0}".format(
|
||||||
|
self.actual_user or u'?'), host=self._play_context.remote_addr
|
||||||
|
)
|
||||||
|
self._connected = True
|
||||||
|
|
||||||
|
def exec_command(self, cmd, in_data=None, sudoable=False):
|
||||||
|
""" Run a command on the docker host """
|
||||||
|
super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)
|
||||||
|
|
||||||
|
local_cmd = self._build_exec_cmd([self._play_context.executable, '-c', cmd])
|
||||||
|
|
||||||
|
display.vvv(u"EXEC {0}".format(to_text(local_cmd)), host=self._play_context.remote_addr)
|
||||||
|
display.debug("opening command with Popen()")
|
||||||
|
|
||||||
|
local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]
|
||||||
|
|
||||||
|
p = subprocess.Popen(
|
||||||
|
local_cmd,
|
||||||
|
stdin=subprocess.PIPE,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
|
)
|
||||||
|
display.debug("done running command with Popen()")
|
||||||
|
|
||||||
|
if self.become and self.become.expect_prompt() and sudoable:
|
||||||
|
fcntl.fcntl(p.stdout, fcntl.F_SETFL, fcntl.fcntl(p.stdout, fcntl.F_GETFL) | os.O_NONBLOCK)
|
||||||
|
fcntl.fcntl(p.stderr, fcntl.F_SETFL, fcntl.fcntl(p.stderr, fcntl.F_GETFL) | os.O_NONBLOCK)
|
||||||
|
selector = selectors.DefaultSelector()
|
||||||
|
selector.register(p.stdout, selectors.EVENT_READ)
|
||||||
|
selector.register(p.stderr, selectors.EVENT_READ)
|
||||||
|
|
||||||
|
become_output = b''
|
||||||
|
try:
|
||||||
|
while not self.become.check_success(become_output) and not self.become.check_password_prompt(become_output):
|
||||||
|
events = selector.select(self._play_context.timeout)
|
||||||
|
if not events:
|
||||||
|
stdout, stderr = p.communicate()
|
||||||
|
raise AnsibleError('timeout waiting for privilege escalation password prompt:\n' + to_native(become_output))
|
||||||
|
|
||||||
|
for key, event in events:
|
||||||
|
if key.fileobj == p.stdout:
|
||||||
|
chunk = p.stdout.read()
|
||||||
|
elif key.fileobj == p.stderr:
|
||||||
|
chunk = p.stderr.read()
|
||||||
|
|
||||||
|
if not chunk:
|
||||||
|
stdout, stderr = p.communicate()
|
||||||
|
raise AnsibleError('privilege output closed while waiting for password prompt:\n' + to_native(become_output))
|
||||||
|
become_output += chunk
|
||||||
|
finally:
|
||||||
|
selector.close()
|
||||||
|
|
||||||
|
if not self.become.check_success(become_output):
|
||||||
|
become_pass = self.become.get_option('become_pass', playcontext=self._play_context)
|
||||||
|
p.stdin.write(to_bytes(become_pass, errors='surrogate_or_strict') + b'\n')
|
||||||
|
fcntl.fcntl(p.stdout, fcntl.F_SETFL, fcntl.fcntl(p.stdout, fcntl.F_GETFL) & ~os.O_NONBLOCK)
|
||||||
|
fcntl.fcntl(p.stderr, fcntl.F_SETFL, fcntl.fcntl(p.stderr, fcntl.F_GETFL) & ~os.O_NONBLOCK)
|
||||||
|
|
||||||
|
display.debug("getting output with communicate()")
|
||||||
|
stdout, stderr = p.communicate(in_data)
|
||||||
|
display.debug("done communicating")
|
||||||
|
|
||||||
|
display.debug("done with docker.exec_command()")
|
||||||
|
return (p.returncode, stdout, stderr)
|
||||||
|
|
||||||
|
def _prefix_login_path(self, remote_path):
|
||||||
|
''' Make sure that we put files into a standard path
|
||||||
|
|
||||||
|
If a path is relative, then we need to choose where to put it.
|
||||||
|
ssh chooses $HOME but we aren't guaranteed that a home dir will
|
||||||
|
exist in any given chroot. So for now we're choosing "/" instead.
|
||||||
|
This also happens to be the former default.
|
||||||
|
|
||||||
|
Can revisit using $HOME instead if it's a problem
|
||||||
|
'''
|
||||||
|
if getattr(self._shell, "_IS_WINDOWS", False):
|
||||||
|
import ntpath
|
||||||
|
return ntpath.normpath(remote_path)
|
||||||
|
else:
|
||||||
|
if not remote_path.startswith(os.path.sep):
|
||||||
|
remote_path = os.path.join(os.path.sep, remote_path)
|
||||||
|
return os.path.normpath(remote_path)
|
||||||
|
|
||||||
|
def put_file(self, in_path, out_path):
|
||||||
|
""" Transfer a file from local to docker container """
|
||||||
|
super(Connection, self).put_file(in_path, out_path)
|
||||||
|
display.vvv("PUT %s TO %s" % (in_path, out_path), host=self._play_context.remote_addr)
|
||||||
|
|
||||||
|
out_path = self._prefix_login_path(out_path)
|
||||||
|
if not os.path.exists(to_bytes(in_path, errors='surrogate_or_strict')):
|
||||||
|
raise AnsibleFileNotFound(
|
||||||
|
"file or module does not exist: %s" % to_native(in_path))
|
||||||
|
|
||||||
|
out_path = shlex_quote(out_path)
|
||||||
|
# Older docker doesn't have native support for copying files into
|
||||||
|
# running containers, so we use docker exec to implement this
|
||||||
|
# Although docker version 1.8 and later provide support, the
|
||||||
|
# owner and group of the files are always set to root
|
||||||
|
with open(to_bytes(in_path, errors='surrogate_or_strict'), 'rb') as in_file:
|
||||||
|
if not os.fstat(in_file.fileno()).st_size:
|
||||||
|
count = ' count=0'
|
||||||
|
else:
|
||||||
|
count = ''
|
||||||
|
args = self._build_exec_cmd([self._play_context.executable, "-c", "dd of=%s bs=%s%s" % (out_path, BUFSIZE, count)])
|
||||||
|
args = [to_bytes(i, errors='surrogate_or_strict') for i in args]
|
||||||
|
try:
|
||||||
|
p = subprocess.Popen(args, stdin=in_file,
|
||||||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
except OSError:
|
||||||
|
raise AnsibleError("docker connection requires dd command in the container to put files")
|
||||||
|
stdout, stderr = p.communicate()
|
||||||
|
|
||||||
|
if p.returncode != 0:
|
||||||
|
raise AnsibleError("failed to transfer file %s to %s:\n%s\n%s" %
|
||||||
|
(to_native(in_path), to_native(out_path), to_native(stdout), to_native(stderr)))
|
||||||
|
|
||||||
|
def fetch_file(self, in_path, out_path):
|
||||||
|
""" Fetch a file from container to local. """
|
||||||
|
super(Connection, self).fetch_file(in_path, out_path)
|
||||||
|
display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self._play_context.remote_addr)
|
||||||
|
|
||||||
|
in_path = self._prefix_login_path(in_path)
|
||||||
|
# out_path is the final file path, but docker takes a directory, not a
|
||||||
|
# file path
|
||||||
|
out_dir = os.path.dirname(out_path)
|
||||||
|
|
||||||
|
args = [self.docker_cmd, "cp", "%s:%s" % (self._play_context.remote_addr, in_path), out_dir]
|
||||||
|
args = [to_bytes(i, errors='surrogate_or_strict') for i in args]
|
||||||
|
|
||||||
|
p = subprocess.Popen(args, stdin=subprocess.PIPE,
|
||||||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
p.communicate()
|
||||||
|
|
||||||
|
if getattr(self._shell, "_IS_WINDOWS", False):
|
||||||
|
import ntpath
|
||||||
|
actual_out_path = ntpath.join(out_dir, ntpath.basename(in_path))
|
||||||
|
else:
|
||||||
|
actual_out_path = os.path.join(out_dir, os.path.basename(in_path))
|
||||||
|
|
||||||
|
if p.returncode != 0:
|
||||||
|
# Older docker doesn't have native support for fetching files command `cp`
|
||||||
|
# If `cp` fails, try to use `dd` instead
|
||||||
|
args = self._build_exec_cmd([self._play_context.executable, "-c", "dd if=%s bs=%s" % (in_path, BUFSIZE)])
|
||||||
|
args = [to_bytes(i, errors='surrogate_or_strict') for i in args]
|
||||||
|
with open(to_bytes(actual_out_path, errors='surrogate_or_strict'), 'wb') as out_file:
|
||||||
|
try:
|
||||||
|
p = subprocess.Popen(args, stdin=subprocess.PIPE,
|
||||||
|
stdout=out_file, stderr=subprocess.PIPE)
|
||||||
|
except OSError:
|
||||||
|
raise AnsibleError("docker connection requires dd command in the container to put files")
|
||||||
|
stdout, stderr = p.communicate()
|
||||||
|
|
||||||
|
if p.returncode != 0:
|
||||||
|
raise AnsibleError("failed to fetch file %s to %s:\n%s\n%s" % (in_path, out_path, stdout, stderr))
|
||||||
|
|
||||||
|
# Rename if needed
|
||||||
|
if actual_out_path != out_path:
|
||||||
|
os.rename(to_bytes(actual_out_path, errors='strict'), to_bytes(out_path, errors='strict'))
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
""" Terminate the connection. Nothing to do for Docker"""
|
||||||
|
super(Connection, self).close()
|
||||||
|
self._connected = False
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# Based on local.py (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
|
# Based on local.py (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
|
||||||
# Based on chroot.py (c) 2013, Maykel Moya <mmoya@speedyrails.com>
|
# Based on chroot.py (c) 2013, Maykel Moya <mmoya@speedyrails.com>
|
||||||
# Copyright (c) 2013, Michael Scherer <misc@zarb.org>
|
# Copyright (c) 2013, Michael Scherer <misc@zarb.org>
|
||||||
@@ -10,7 +9,7 @@ __metaclass__ = type
|
|||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
author: Michael Scherer (@msherer) <misc@zarb.org>
|
author: Michael Scherer (@msherer) <misc@zarb.org>
|
||||||
name: funcd
|
connection: funcd
|
||||||
short_description: Use funcd to connect to target
|
short_description: Use funcd to connect to target
|
||||||
description:
|
description:
|
||||||
- This transport permits you to use Ansible over Func.
|
- This transport permits you to use Ansible over Func.
|
||||||
@@ -38,13 +37,12 @@ import tempfile
|
|||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
from ansible.errors import AnsibleError
|
from ansible.errors import AnsibleError
|
||||||
from ansible.plugins.connection import ConnectionBase
|
|
||||||
from ansible.utils.display import Display
|
from ansible.utils.display import Display
|
||||||
|
|
||||||
display = Display()
|
display = Display()
|
||||||
|
|
||||||
|
|
||||||
class Connection(ConnectionBase):
|
class Connection(object):
|
||||||
''' Func-based connections '''
|
''' Func-based connections '''
|
||||||
|
|
||||||
has_pipelining = False
|
has_pipelining = False
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# Based on jail.py
|
# Based on jail.py
|
||||||
# (c) 2013, Michael Scherer <misc@zarb.org>
|
# (c) 2013, Michael Scherer <misc@zarb.org>
|
||||||
# (c) 2015, Toshio Kuratomi <tkuratomi@ansible.com>
|
# (c) 2015, Toshio Kuratomi <tkuratomi@ansible.com>
|
||||||
@@ -11,7 +10,7 @@ __metaclass__ = type
|
|||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
author: Stephan Lohse (!UNKNOWN) <dev-github@ploek.org>
|
author: Stephan Lohse (!UNKNOWN) <dev-github@ploek.org>
|
||||||
name: iocage
|
connection: iocage
|
||||||
short_description: Run tasks in iocage jails
|
short_description: Run tasks in iocage jails
|
||||||
description:
|
description:
|
||||||
- Run commands or put/fetch files to an existing iocage jail
|
- Run commands or put/fetch files to an existing iocage jail
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# Based on local.py by Michael DeHaan <michael.dehaan@gmail.com>
|
# Based on local.py by Michael DeHaan <michael.dehaan@gmail.com>
|
||||||
# and chroot.py by Maykel Moya <mmoya@speedyrails.com>
|
# and chroot.py by Maykel Moya <mmoya@speedyrails.com>
|
||||||
# Copyright (c) 2013, Michael Scherer <misc@zarb.org>
|
# Copyright (c) 2013, Michael Scherer <misc@zarb.org>
|
||||||
@@ -11,7 +10,7 @@ __metaclass__ = type
|
|||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
author: Ansible Core Team
|
author: Ansible Core Team
|
||||||
name: jail
|
connection: jail
|
||||||
short_description: Run tasks in jails
|
short_description: Run tasks in jails
|
||||||
description:
|
description:
|
||||||
- Run commands or put/fetch files to an existing jail
|
- Run commands or put/fetch files to an existing jail
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# (c) 2015, Joerg Thalheim <joerg@higgsboson.tk>
|
# (c) 2015, Joerg Thalheim <joerg@higgsboson.tk>
|
||||||
# Copyright (c) 2017 Ansible Project
|
# Copyright (c) 2017 Ansible Project
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
@@ -8,7 +7,7 @@ __metaclass__ = type
|
|||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
author: Joerg Thalheim (!UNKNOWN) <joerg@higgsboson.tk>
|
author: Joerg Thalheim (!UNKNOWN) <joerg@higgsboson.tk>
|
||||||
name: lxc
|
connection: lxc
|
||||||
short_description: Run tasks in lxc containers via lxc python library
|
short_description: Run tasks in lxc containers via lxc python library
|
||||||
description:
|
description:
|
||||||
- Run commands or put/fetch files to an existing lxc container using lxc python library
|
- Run commands or put/fetch files to an existing lxc container using lxc python library
|
||||||
@@ -87,7 +86,7 @@ class Connection(ConnectionBase):
|
|||||||
write_fds = []
|
write_fds = []
|
||||||
while len(read_fds) > 0 or len(write_fds) > 0:
|
while len(read_fds) > 0 or len(write_fds) > 0:
|
||||||
try:
|
try:
|
||||||
ready_reads, ready_writes, dummy = select.select(read_fds, write_fds, [])
|
ready_reads, ready_writes, _ = select.select(read_fds, write_fds, [])
|
||||||
except select.error as e:
|
except select.error as e:
|
||||||
if e.args[0] == errno.EINTR:
|
if e.args[0] == errno.EINTR:
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# (c) 2016 Matt Clay <matt@mystile.com>
|
# (c) 2016 Matt Clay <matt@mystile.com>
|
||||||
# (c) 2017 Ansible Project
|
# (c) 2017 Ansible Project
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
@@ -8,14 +7,14 @@ __metaclass__ = type
|
|||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
author: Matt Clay (@mattclay) <matt@mystile.com>
|
author: Matt Clay (@mattclay) <matt@mystile.com>
|
||||||
name: lxd
|
connection: lxd
|
||||||
short_description: Run tasks in lxc containers via lxc CLI
|
short_description: Run tasks in lxc containers via lxc CLI
|
||||||
description:
|
description:
|
||||||
- Run commands or put/fetch files to an existing lxc container using lxc CLI
|
- Run commands or put/fetch files to an existing lxc container using lxc CLI
|
||||||
options:
|
options:
|
||||||
remote_addr:
|
remote_addr:
|
||||||
description:
|
description:
|
||||||
- Container identifier.
|
- Container identifier
|
||||||
default: inventory_hostname
|
default: inventory_hostname
|
||||||
vars:
|
vars:
|
||||||
- name: ansible_host
|
- name: ansible_host
|
||||||
@@ -27,19 +26,6 @@ DOCUMENTATION = '''
|
|||||||
vars:
|
vars:
|
||||||
- name: ansible_executable
|
- name: ansible_executable
|
||||||
- name: ansible_lxd_executable
|
- name: ansible_lxd_executable
|
||||||
remote:
|
|
||||||
description:
|
|
||||||
- Name of the LXD remote to use.
|
|
||||||
default: local
|
|
||||||
vars:
|
|
||||||
- name: ansible_lxd_remote
|
|
||||||
version_added: 2.0.0
|
|
||||||
project:
|
|
||||||
description:
|
|
||||||
- Name of the LXD project to use.
|
|
||||||
vars:
|
|
||||||
- name: ansible_lxd_project
|
|
||||||
version_added: 2.0.0
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import os
|
import os
|
||||||
@@ -84,15 +70,7 @@ class Connection(ConnectionBase):
|
|||||||
|
|
||||||
self._display.vvv(u"EXEC {0}".format(cmd), host=self._host)
|
self._display.vvv(u"EXEC {0}".format(cmd), host=self._host)
|
||||||
|
|
||||||
local_cmd = [self._lxc_cmd]
|
local_cmd = [self._lxc_cmd, "exec", self._host, "--", self._play_context.executable, "-c", cmd]
|
||||||
if self.get_option("project"):
|
|
||||||
local_cmd.extend(["--project", self.get_option("project")])
|
|
||||||
local_cmd.extend([
|
|
||||||
"exec",
|
|
||||||
"%s:%s" % (self.get_option("remote"), self._host),
|
|
||||||
"--",
|
|
||||||
self._play_context.executable, "-c", cmd
|
|
||||||
])
|
|
||||||
|
|
||||||
local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]
|
local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]
|
||||||
in_data = to_bytes(in_data, errors='surrogate_or_strict', nonstring='passthru')
|
in_data = to_bytes(in_data, errors='surrogate_or_strict', nonstring='passthru')
|
||||||
@@ -120,14 +98,7 @@ class Connection(ConnectionBase):
|
|||||||
if not os.path.isfile(to_bytes(in_path, errors='surrogate_or_strict')):
|
if not os.path.isfile(to_bytes(in_path, errors='surrogate_or_strict')):
|
||||||
raise AnsibleFileNotFound("input path is not a file: %s" % in_path)
|
raise AnsibleFileNotFound("input path is not a file: %s" % in_path)
|
||||||
|
|
||||||
local_cmd = [self._lxc_cmd]
|
local_cmd = [self._lxc_cmd, "file", "push", in_path, self._host + "/" + out_path]
|
||||||
if self.get_option("project"):
|
|
||||||
local_cmd.extend(["--project", self.get_option("project")])
|
|
||||||
local_cmd.extend([
|
|
||||||
"file", "push",
|
|
||||||
in_path,
|
|
||||||
"%s:%s/%s" % (self.get_option("remote"), self._host, out_path)
|
|
||||||
])
|
|
||||||
|
|
||||||
local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]
|
local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]
|
||||||
|
|
||||||
@@ -140,14 +111,7 @@ class Connection(ConnectionBase):
|
|||||||
|
|
||||||
self._display.vvv(u"FETCH {0} TO {1}".format(in_path, out_path), host=self._host)
|
self._display.vvv(u"FETCH {0} TO {1}".format(in_path, out_path), host=self._host)
|
||||||
|
|
||||||
local_cmd = [self._lxc_cmd]
|
local_cmd = [self._lxc_cmd, "file", "pull", self._host + "/" + in_path, out_path]
|
||||||
if self.get_option("project"):
|
|
||||||
local_cmd.extend(["--project", self.get_option("project")])
|
|
||||||
local_cmd.extend([
|
|
||||||
"file", "pull",
|
|
||||||
"%s:%s/%s" % (self.get_option("remote"), self._host, in_path),
|
|
||||||
out_path
|
|
||||||
])
|
|
||||||
|
|
||||||
local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]
|
local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]
|
||||||
|
|
||||||
|
|||||||
173
plugins/connection/oc.py
Normal file
173
plugins/connection/oc.py
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
# Based on the docker connection plugin
|
||||||
|
#
|
||||||
|
# Connection plugin for configuring kubernetes containers with kubectl
|
||||||
|
# (c) 2017, XuXinkun <xuxinkun@gmail.com>
|
||||||
|
#
|
||||||
|
# This file is part of Ansible
|
||||||
|
#
|
||||||
|
# Ansible is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Ansible is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
DOCUMENTATION = '''
|
||||||
|
author:
|
||||||
|
- xuxinkun (!UNKNOWN)
|
||||||
|
|
||||||
|
connection: oc
|
||||||
|
|
||||||
|
short_description: Execute tasks in pods running on OpenShift.
|
||||||
|
|
||||||
|
description:
|
||||||
|
- Use the oc exec command to run tasks in, or put/fetch files to, pods running on the OpenShift
|
||||||
|
container platform.
|
||||||
|
|
||||||
|
|
||||||
|
requirements:
|
||||||
|
- oc (go binary)
|
||||||
|
|
||||||
|
options:
|
||||||
|
oc_pod:
|
||||||
|
description:
|
||||||
|
- Pod name. Required when the host name does not match pod name.
|
||||||
|
default: ''
|
||||||
|
vars:
|
||||||
|
- name: ansible_oc_pod
|
||||||
|
env:
|
||||||
|
- name: K8S_AUTH_POD
|
||||||
|
oc_container:
|
||||||
|
description:
|
||||||
|
- Container name. Required when a pod contains more than one container.
|
||||||
|
default: ''
|
||||||
|
vars:
|
||||||
|
- name: ansible_oc_container
|
||||||
|
env:
|
||||||
|
- name: K8S_AUTH_CONTAINER
|
||||||
|
oc_namespace:
|
||||||
|
description:
|
||||||
|
- The namespace of the pod
|
||||||
|
default: ''
|
||||||
|
vars:
|
||||||
|
- name: ansible_oc_namespace
|
||||||
|
env:
|
||||||
|
- name: K8S_AUTH_NAMESPACE
|
||||||
|
oc_extra_args:
|
||||||
|
description:
|
||||||
|
- Extra arguments to pass to the oc command line.
|
||||||
|
default: ''
|
||||||
|
vars:
|
||||||
|
- name: ansible_oc_extra_args
|
||||||
|
env:
|
||||||
|
- name: K8S_AUTH_EXTRA_ARGS
|
||||||
|
oc_kubeconfig:
|
||||||
|
description:
|
||||||
|
- Path to a oc config file. Defaults to I(~/.kube/conig)
|
||||||
|
default: ''
|
||||||
|
vars:
|
||||||
|
- name: ansible_oc_kubeconfig
|
||||||
|
- name: ansible_oc_config
|
||||||
|
env:
|
||||||
|
- name: K8S_AUTH_KUBECONFIG
|
||||||
|
oc_context:
|
||||||
|
description:
|
||||||
|
- The name of a context found in the K8s config file.
|
||||||
|
default: ''
|
||||||
|
vars:
|
||||||
|
- name: ansible_oc_context
|
||||||
|
env:
|
||||||
|
- name: K8S_AUTH_CONTEXT
|
||||||
|
oc_host:
|
||||||
|
description:
|
||||||
|
- URL for accessing the API.
|
||||||
|
default: ''
|
||||||
|
vars:
|
||||||
|
- name: ansible_oc_host
|
||||||
|
- name: ansible_oc_server
|
||||||
|
env:
|
||||||
|
- name: K8S_AUTH_HOST
|
||||||
|
- name: K8S_AUTH_SERVER
|
||||||
|
oc_token:
|
||||||
|
description:
|
||||||
|
- API authentication bearer token.
|
||||||
|
vars:
|
||||||
|
- name: ansible_oc_token
|
||||||
|
- name: ansible_oc_api_key
|
||||||
|
env:
|
||||||
|
- name: K8S_AUTH_TOKEN
|
||||||
|
- name: K8S_AUTH_API_KEY
|
||||||
|
client_cert:
|
||||||
|
description:
|
||||||
|
- Path to a certificate used to authenticate with the API.
|
||||||
|
default: ''
|
||||||
|
vars:
|
||||||
|
- name: ansible_oc_cert_file
|
||||||
|
- name: ansible_oc_client_cert
|
||||||
|
env:
|
||||||
|
- name: K8S_AUTH_CERT_FILE
|
||||||
|
aliases: [ oc_cert_file ]
|
||||||
|
client_key:
|
||||||
|
description:
|
||||||
|
- Path to a key file used to authenticate with the API.
|
||||||
|
default: ''
|
||||||
|
vars:
|
||||||
|
- name: ansible_oc_key_file
|
||||||
|
- name: ansible_oc_client_key
|
||||||
|
env:
|
||||||
|
- name: K8S_AUTH_KEY_FILE
|
||||||
|
aliases: [ oc_key_file ]
|
||||||
|
ca_cert:
|
||||||
|
description:
|
||||||
|
- Path to a CA certificate used to authenticate with the API.
|
||||||
|
default: ''
|
||||||
|
vars:
|
||||||
|
- name: ansible_oc_ssl_ca_cert
|
||||||
|
- name: ansible_oc_ca_cert
|
||||||
|
env:
|
||||||
|
- name: K8S_AUTH_SSL_CA_CERT
|
||||||
|
aliases: [ oc_ssl_ca_cert ]
|
||||||
|
validate_certs:
|
||||||
|
description:
|
||||||
|
- Whether or not to verify the API server's SSL certificate. Defaults to I(true).
|
||||||
|
default: ''
|
||||||
|
vars:
|
||||||
|
- name: ansible_oc_verify_ssl
|
||||||
|
- name: ansible_oc_validate_certs
|
||||||
|
env:
|
||||||
|
- name: K8S_AUTH_VERIFY_SSL
|
||||||
|
aliases: [ oc_verify_ssl ]
|
||||||
|
'''
|
||||||
|
|
||||||
|
from ansible_collections.community.kubernetes.plugins.connection.kubectl import Connection as KubectlConnection
|
||||||
|
|
||||||
|
|
||||||
|
CONNECTION_TRANSPORT = 'community.general.oc'
|
||||||
|
|
||||||
|
CONNECTION_OPTIONS = {
|
||||||
|
'oc_container': '-c',
|
||||||
|
'oc_namespace': '-n',
|
||||||
|
'oc_kubeconfig': '--config',
|
||||||
|
'oc_context': '--context',
|
||||||
|
'oc_host': '--server',
|
||||||
|
'client_cert': '--client-certificate',
|
||||||
|
'client_key': '--client-key',
|
||||||
|
'ca_cert': '--certificate-authority',
|
||||||
|
'validate_certs': '--insecure-skip-tls-verify',
|
||||||
|
'oc_token': '--token'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Connection(KubectlConnection):
|
||||||
|
''' Local oc based connections '''
|
||||||
|
transport = CONNECTION_TRANSPORT
|
||||||
|
connection_options = CONNECTION_OPTIONS
|
||||||
|
documentation = DOCUMENTATION
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# Based on the buildah connection plugin
|
# Based on the buildah connection plugin
|
||||||
# Copyright (c) 2017 Ansible Project
|
# Copyright (c) 2017 Ansible Project
|
||||||
# 2018 Kushal Das
|
# 2018 Kushal Das
|
||||||
@@ -12,7 +11,7 @@ __metaclass__ = type
|
|||||||
|
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
name: qubes
|
connection: qubes
|
||||||
short_description: Interact with an existing QubesOS AppVM
|
short_description: Interact with an existing QubesOS AppVM
|
||||||
|
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# Based on local.py (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
|
# Based on local.py (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
|
||||||
# Based on chroot.py (c) 2013, Maykel Moya <mmoya@speedyrails.com>
|
# Based on chroot.py (c) 2013, Maykel Moya <mmoya@speedyrails.com>
|
||||||
# Based on func.py
|
# Based on func.py
|
||||||
@@ -11,7 +10,7 @@ __metaclass__ = type
|
|||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
author: Michael Scherer (@mscherer) <misc@zarb.org>
|
author: Michael Scherer (@mscherer) <misc@zarb.org>
|
||||||
name: saltstack
|
connection: saltstack
|
||||||
short_description: Allow ansible to piggyback on salt minions
|
short_description: Allow ansible to piggyback on salt minions
|
||||||
description:
|
description:
|
||||||
- This allows you to use existing Saltstack infrastructure to connect to targets.
|
- This allows you to use existing Saltstack infrastructure to connect to targets.
|
||||||
@@ -58,7 +57,7 @@ class Connection(ConnectionBase):
|
|||||||
self._connected = True
|
self._connected = True
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def exec_command(self, cmd, in_data=None, sudoable=False):
|
def exec_command(self, cmd, sudoable=False, in_data=None):
|
||||||
''' run a command on the remote minion '''
|
''' run a command on the remote minion '''
|
||||||
super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)
|
super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# Based on local.py (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
|
# Based on local.py (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
|
||||||
# and chroot.py (c) 2013, Maykel Moya <mmoya@speedyrails.com>
|
# and chroot.py (c) 2013, Maykel Moya <mmoya@speedyrails.com>
|
||||||
# and jail.py (c) 2013, Michael Scherer <misc@zarb.org>
|
# and jail.py (c) 2013, Michael Scherer <misc@zarb.org>
|
||||||
@@ -12,7 +11,7 @@ __metaclass__ = type
|
|||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
author: Ansible Core Team
|
author: Ansible Core Team
|
||||||
name: zone
|
connection: zone
|
||||||
short_description: Run tasks in a zone instance
|
short_description: Run tasks in a zone instance
|
||||||
description:
|
description:
|
||||||
- Run commands or put/fetch files to an existing zone
|
- Run commands or put/fetch files to an existing zone
|
||||||
|
|||||||
62
plugins/doc_fragments/_gcp.py
Normal file
62
plugins/doc_fragments/_gcp.py
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Copyright: (c) 2018, Google Inc.
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
|
||||||
|
class ModuleDocFragment(object):
|
||||||
|
# GCP doc fragment.
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
options:
|
||||||
|
project:
|
||||||
|
description:
|
||||||
|
- The Google Cloud Platform project to use.
|
||||||
|
type: str
|
||||||
|
auth_kind:
|
||||||
|
description:
|
||||||
|
- The type of credential used.
|
||||||
|
type: str
|
||||||
|
required: true
|
||||||
|
choices: [ application, machineaccount, serviceaccount ]
|
||||||
|
service_account_contents:
|
||||||
|
description:
|
||||||
|
- The contents of a Service Account JSON file, either in a dictionary or as a JSON string that represents it.
|
||||||
|
type: jsonarg
|
||||||
|
service_account_file:
|
||||||
|
description:
|
||||||
|
- The path of a Service Account JSON file if serviceaccount is selected as type.
|
||||||
|
type: path
|
||||||
|
service_account_email:
|
||||||
|
description:
|
||||||
|
- An optional service account email address if machineaccount is selected
|
||||||
|
and the user does not wish to use the default email.
|
||||||
|
type: str
|
||||||
|
scopes:
|
||||||
|
description:
|
||||||
|
- Array of scopes to be used.
|
||||||
|
type: list
|
||||||
|
elements: str
|
||||||
|
env_type:
|
||||||
|
description:
|
||||||
|
- Specifies which Ansible environment you're running this module within.
|
||||||
|
- This should not be set unless you know what you're doing.
|
||||||
|
- This only alters the User Agent string for any API requests.
|
||||||
|
type: str
|
||||||
|
notes:
|
||||||
|
- for authentication, you can set service_account_file using the
|
||||||
|
c(gcp_service_account_file) env variable.
|
||||||
|
- for authentication, you can set service_account_contents using the
|
||||||
|
c(GCP_SERVICE_ACCOUNT_CONTENTS) env variable.
|
||||||
|
- For authentication, you can set service_account_email using the
|
||||||
|
C(GCP_SERVICE_ACCOUNT_EMAIL) env variable.
|
||||||
|
- For authentication, you can set auth_kind using the C(GCP_AUTH_KIND) env
|
||||||
|
variable.
|
||||||
|
- For authentication, you can set scopes using the C(GCP_SCOPES) env variable.
|
||||||
|
- Environment variables values will only be used if the playbook values are
|
||||||
|
not set.
|
||||||
|
- The I(service_account_email) and I(service_account_file) options are
|
||||||
|
mutually exclusive.
|
||||||
|
'''
|
||||||
136
plugins/doc_fragments/docker.py
Normal file
136
plugins/doc_fragments/docker.py
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
|
||||||
|
class ModuleDocFragment(object):
|
||||||
|
|
||||||
|
# Docker doc fragment
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
|
||||||
|
options:
|
||||||
|
docker_host:
|
||||||
|
description:
|
||||||
|
- The URL or Unix socket path used to connect to the Docker API. To connect to a remote host, provide the
|
||||||
|
TCP connection string. For example, C(tcp://192.0.2.23:2376). If TLS is used to encrypt the connection,
|
||||||
|
the module will automatically replace C(tcp) in the connection URL with C(https).
|
||||||
|
- If the value is not specified in the task, the value of environment variable C(DOCKER_HOST) will be used
|
||||||
|
instead. If the environment variable is not set, the default value will be used.
|
||||||
|
type: str
|
||||||
|
default: unix://var/run/docker.sock
|
||||||
|
aliases: [ docker_url ]
|
||||||
|
tls_hostname:
|
||||||
|
description:
|
||||||
|
- When verifying the authenticity of the Docker Host server, provide the expected name of the server.
|
||||||
|
- If the value is not specified in the task, the value of environment variable C(DOCKER_TLS_HOSTNAME) will
|
||||||
|
be used instead. If the environment variable is not set, the default value will be used.
|
||||||
|
type: str
|
||||||
|
default: localhost
|
||||||
|
api_version:
|
||||||
|
description:
|
||||||
|
- The version of the Docker API running on the Docker Host.
|
||||||
|
- Defaults to the latest version of the API supported by Docker SDK for Python and the docker daemon.
|
||||||
|
- If the value is not specified in the task, the value of environment variable C(DOCKER_API_VERSION) will be
|
||||||
|
used instead. If the environment variable is not set, the default value will be used.
|
||||||
|
type: str
|
||||||
|
default: auto
|
||||||
|
aliases: [ docker_api_version ]
|
||||||
|
timeout:
|
||||||
|
description:
|
||||||
|
- The maximum amount of time in seconds to wait on a response from the API.
|
||||||
|
- If the value is not specified in the task, the value of environment variable C(DOCKER_TIMEOUT) will be used
|
||||||
|
instead. If the environment variable is not set, the default value will be used.
|
||||||
|
type: int
|
||||||
|
default: 60
|
||||||
|
ca_cert:
|
||||||
|
description:
|
||||||
|
- Use a CA certificate when performing server verification by providing the path to a CA certificate file.
|
||||||
|
- If the value is not specified in the task and the environment variable C(DOCKER_CERT_PATH) is set,
|
||||||
|
the file C(ca.pem) from the directory specified in the environment variable C(DOCKER_CERT_PATH) will be used.
|
||||||
|
type: path
|
||||||
|
aliases: [ tls_ca_cert, cacert_path ]
|
||||||
|
client_cert:
|
||||||
|
description:
|
||||||
|
- Path to the client's TLS certificate file.
|
||||||
|
- If the value is not specified in the task and the environment variable C(DOCKER_CERT_PATH) is set,
|
||||||
|
the file C(cert.pem) from the directory specified in the environment variable C(DOCKER_CERT_PATH) will be used.
|
||||||
|
type: path
|
||||||
|
aliases: [ tls_client_cert, cert_path ]
|
||||||
|
client_key:
|
||||||
|
description:
|
||||||
|
- Path to the client's TLS key file.
|
||||||
|
- If the value is not specified in the task and the environment variable C(DOCKER_CERT_PATH) is set,
|
||||||
|
the file C(key.pem) from the directory specified in the environment variable C(DOCKER_CERT_PATH) will be used.
|
||||||
|
type: path
|
||||||
|
aliases: [ tls_client_key, key_path ]
|
||||||
|
ssl_version:
|
||||||
|
description:
|
||||||
|
- Provide a valid SSL version number. Default value determined by ssl.py module.
|
||||||
|
- If the value is not specified in the task, the value of environment variable C(DOCKER_SSL_VERSION) will be
|
||||||
|
used instead.
|
||||||
|
type: str
|
||||||
|
tls:
|
||||||
|
description:
|
||||||
|
- Secure the connection to the API by using TLS without verifying the authenticity of the Docker host
|
||||||
|
server. Note that if I(validate_certs) is set to C(yes) as well, it will take precedence.
|
||||||
|
- If the value is not specified in the task, the value of environment variable C(DOCKER_TLS) will be used
|
||||||
|
instead. If the environment variable is not set, the default value will be used.
|
||||||
|
type: bool
|
||||||
|
default: no
|
||||||
|
validate_certs:
|
||||||
|
description:
|
||||||
|
- Secure the connection to the API by using TLS and verifying the authenticity of the Docker host server.
|
||||||
|
- If the value is not specified in the task, the value of environment variable C(DOCKER_TLS_VERIFY) will be
|
||||||
|
used instead. If the environment variable is not set, the default value will be used.
|
||||||
|
type: bool
|
||||||
|
default: no
|
||||||
|
aliases: [ tls_verify ]
|
||||||
|
debug:
|
||||||
|
description:
|
||||||
|
- Debug mode
|
||||||
|
type: bool
|
||||||
|
default: no
|
||||||
|
|
||||||
|
notes:
|
||||||
|
- Connect to the Docker daemon by providing parameters with each task or by defining environment variables.
|
||||||
|
You can define C(DOCKER_HOST), C(DOCKER_TLS_HOSTNAME), C(DOCKER_API_VERSION), C(DOCKER_CERT_PATH), C(DOCKER_SSL_VERSION),
|
||||||
|
C(DOCKER_TLS), C(DOCKER_TLS_VERIFY) and C(DOCKER_TIMEOUT). If you are using docker machine, run the script shipped
|
||||||
|
with the product that sets up the environment. It will set these variables for you. See
|
||||||
|
U(https://docs.docker.com/machine/reference/env/) for more details.
|
||||||
|
- When connecting to Docker daemon with TLS, you might need to install additional Python packages.
|
||||||
|
For the Docker SDK for Python, version 2.4 or newer, this can be done by installing C(docker[tls]) with M(ansible.builtin.pip).
|
||||||
|
- Note that the Docker SDK for Python only allows to specify the path to the Docker configuration for very few functions.
|
||||||
|
In general, it will use C($HOME/.docker/config.json) if the C(DOCKER_CONFIG) environment variable is not specified,
|
||||||
|
and use C($DOCKER_CONFIG/config.json) otherwise.
|
||||||
|
'''
|
||||||
|
|
||||||
|
# Additional, more specific stuff for minimal Docker SDK for Python version < 2.0
|
||||||
|
|
||||||
|
DOCKER_PY_1_DOCUMENTATION = r'''
|
||||||
|
options: {}
|
||||||
|
requirements:
|
||||||
|
- "Docker SDK for Python: Please note that the L(docker-py,https://pypi.org/project/docker-py/)
|
||||||
|
Python module has been superseded by L(docker,https://pypi.org/project/docker/)
|
||||||
|
(see L(here,https://github.com/docker/docker-py/issues/1310) for details).
|
||||||
|
For Python 2.6, C(docker-py) must be used. Otherwise, it is recommended to
|
||||||
|
install the C(docker) Python module. Note that both modules should *not*
|
||||||
|
be installed at the same time. Also note that when both modules are installed
|
||||||
|
and one of them is uninstalled, the other might no longer function and a
|
||||||
|
reinstall of it is required."
|
||||||
|
'''
|
||||||
|
|
||||||
|
# Additional, more specific stuff for minimal Docker SDK for Python version >= 2.0.
|
||||||
|
# Note that Docker SDK for Python >= 2.0 requires Python 2.7 or newer.
|
||||||
|
|
||||||
|
DOCKER_PY_2_DOCUMENTATION = r'''
|
||||||
|
options: {}
|
||||||
|
requirements:
|
||||||
|
- "Python >= 2.7"
|
||||||
|
- "Docker SDK for Python: Please note that the L(docker-py,https://pypi.org/project/docker-py/)
|
||||||
|
Python module has been superseded by L(docker,https://pypi.org/project/docker/)
|
||||||
|
(see L(here,https://github.com/docker/docker-py/issues/1310) for details).
|
||||||
|
This module does *not* work with docker-py."
|
||||||
|
'''
|
||||||
23
plugins/doc_fragments/hetzner.py
Normal file
23
plugins/doc_fragments/hetzner.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Copyright: (c) 2019 Felix Fontein <felix@fontein.de>
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
|
||||||
|
class ModuleDocFragment(object):
|
||||||
|
|
||||||
|
# Standard files documentation fragment
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
options:
|
||||||
|
hetzner_user:
|
||||||
|
description: The username for the Robot webservice user.
|
||||||
|
type: str
|
||||||
|
required: yes
|
||||||
|
hetzner_password:
|
||||||
|
description: The password for the Robot webservice user.
|
||||||
|
type: str
|
||||||
|
required: yes
|
||||||
|
'''
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# Copyright: (c) 2018, Hewlett Packard Enterprise Development LP
|
# Copyright: (c) 2018, Hewlett Packard Enterprise Development LP
|
||||||
# GNU General Public License v3.0+
|
# GNU General Public License v3.0+
|
||||||
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# Copyright: (c) 2018, Huawei Inc.
|
# Copyright: (c) 2018, Huawei Inc.
|
||||||
# GNU General Public License v3.0+
|
# GNU General Public License v3.0+
|
||||||
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|||||||
133
plugins/doc_fragments/kubevirt_common_options.py
Normal file
133
plugins/doc_fragments/kubevirt_common_options.py
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Copyright: (c) 2018, KubeVirt Team <@kubevirt>
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
|
||||||
|
class ModuleDocFragment(object):
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
options:
|
||||||
|
resource_definition:
|
||||||
|
description:
|
||||||
|
- "A partial YAML definition of the object being created/updated. Here you can define Kubernetes
|
||||||
|
resource parameters not covered by this module's parameters."
|
||||||
|
- "NOTE: I(resource_definition) has lower priority than module parameters. If you try to define e.g.
|
||||||
|
I(metadata.namespace) here, that value will be ignored and I(namespace) used instead."
|
||||||
|
aliases:
|
||||||
|
- definition
|
||||||
|
- inline
|
||||||
|
type: dict
|
||||||
|
wait:
|
||||||
|
description:
|
||||||
|
- "I(True) if the module should wait for the resource to get into desired state."
|
||||||
|
type: bool
|
||||||
|
default: yes
|
||||||
|
force:
|
||||||
|
description:
|
||||||
|
- If set to C(no), and I(state) is C(present), an existing object will be replaced.
|
||||||
|
type: bool
|
||||||
|
default: no
|
||||||
|
wait_timeout:
|
||||||
|
description:
|
||||||
|
- The amount of time in seconds the module should wait for the resource to get into desired state.
|
||||||
|
type: int
|
||||||
|
default: 120
|
||||||
|
wait_sleep:
|
||||||
|
description:
|
||||||
|
- Number of seconds to sleep between checks.
|
||||||
|
default: 5
|
||||||
|
version_added: '0.2.0'
|
||||||
|
memory:
|
||||||
|
description:
|
||||||
|
- The amount of memory to be requested by virtual machine.
|
||||||
|
- For example 1024Mi.
|
||||||
|
type: str
|
||||||
|
memory_limit:
|
||||||
|
description:
|
||||||
|
- The maximum memory to be used by virtual machine.
|
||||||
|
- For example 1024Mi.
|
||||||
|
type: str
|
||||||
|
machine_type:
|
||||||
|
description:
|
||||||
|
- QEMU machine type is the actual chipset of the virtual machine.
|
||||||
|
type: str
|
||||||
|
merge_type:
|
||||||
|
description:
|
||||||
|
- Whether to override the default patch merge approach with a specific type.
|
||||||
|
- If more than one merge type is given, the merge types will be tried in order.
|
||||||
|
- "Defaults to C(['strategic-merge', 'merge']), which is ideal for using the same parameters
|
||||||
|
on resource kinds that combine Custom Resources and built-in resources, as
|
||||||
|
Custom Resource Definitions typically aren't updatable by the usual strategic merge."
|
||||||
|
- "See U(https://kubernetes.io/docs/tasks/run-application/update-api-object-kubectl-patch/#use-a-json-merge-patch-to-update-a-deployment)"
|
||||||
|
type: list
|
||||||
|
choices: [ json, merge, strategic-merge ]
|
||||||
|
cpu_shares:
|
||||||
|
description:
|
||||||
|
- "Specify CPU shares."
|
||||||
|
type: int
|
||||||
|
cpu_limit:
|
||||||
|
description:
|
||||||
|
- "Is converted to its millicore value and multiplied by 100. The resulting value is the total amount of CPU time that a container can use
|
||||||
|
every 100ms. A virtual machine cannot use more than its share of CPU time during this interval."
|
||||||
|
type: int
|
||||||
|
cpu_cores:
|
||||||
|
description:
|
||||||
|
- "Number of CPU cores."
|
||||||
|
type: int
|
||||||
|
cpu_model:
|
||||||
|
description:
|
||||||
|
- "CPU model."
|
||||||
|
- "You can check list of available models here: U(https://github.com/libvirt/libvirt/blob/master/src/cpu_map/index.xml)."
|
||||||
|
- "I(Note:) User can define default CPU model via as I(default-cpu-model) in I(kubevirt-config) I(ConfigMap), if not set I(host-model) is used."
|
||||||
|
- "I(Note:) Be sure that node CPU model where you run a VM, has the same or higher CPU family."
|
||||||
|
- "I(Note:) If CPU model wasn't defined, the VM will have CPU model closest to one that used on the node where the VM is running."
|
||||||
|
type: str
|
||||||
|
bootloader:
|
||||||
|
description:
|
||||||
|
- "Specify the bootloader of the virtual machine."
|
||||||
|
- "All virtual machines use BIOS by default for booting."
|
||||||
|
type: str
|
||||||
|
smbios_uuid:
|
||||||
|
description:
|
||||||
|
- "In order to provide a consistent view on the virtualized hardware for the guest OS, the SMBIOS UUID can be set."
|
||||||
|
type: str
|
||||||
|
cpu_features:
|
||||||
|
description:
|
||||||
|
- "List of dictionary to fine-tune features provided by the selected CPU model."
|
||||||
|
- "I(Note): Policy attribute can either be omitted or contain one of the following policies: force, require, optional, disable, forbid."
|
||||||
|
- "I(Note): In case a policy is omitted for a feature, it will default to require."
|
||||||
|
- "More information about policies: U(https://libvirt.org/formatdomain.html#elementsCPU)"
|
||||||
|
type: list
|
||||||
|
headless:
|
||||||
|
description:
|
||||||
|
- "Specify if the virtual machine should have attached a minimal Video and Graphics device configuration."
|
||||||
|
- "By default a minimal Video and Graphics device configuration will be applied to the VirtualMachineInstance. The video device is vga
|
||||||
|
compatible and comes with a memory size of 16 MB."
|
||||||
|
hugepage_size:
|
||||||
|
description:
|
||||||
|
- "Specify huge page size."
|
||||||
|
type: str
|
||||||
|
tablets:
|
||||||
|
description:
|
||||||
|
- "Specify tablets to be used as input devices"
|
||||||
|
type: list
|
||||||
|
hostname:
|
||||||
|
description:
|
||||||
|
- "Specifies the hostname of the virtual machine. The hostname will be set either by dhcp, cloud-init if configured or virtual machine
|
||||||
|
name will be used."
|
||||||
|
subdomain:
|
||||||
|
description:
|
||||||
|
- "If specified, the fully qualified virtual machine hostname will be hostname.subdomain.namespace.svc.cluster_domain. If not specified,
|
||||||
|
the virtual machine will not have a domain name at all. The DNS entry will resolve to the virtual machine, no matter if the virtual machine
|
||||||
|
itself can pick up a hostname."
|
||||||
|
requirements:
|
||||||
|
- python >= 2.7
|
||||||
|
- openshift >= 0.8.2
|
||||||
|
notes:
|
||||||
|
- "In order to use this module you have to install Openshift Python SDK.
|
||||||
|
To ensure it's installed with correct version you can create the following task:
|
||||||
|
I(pip: name=openshift>=0.8.2)"
|
||||||
|
'''
|
||||||
103
plugins/doc_fragments/kubevirt_vm_options.py
Normal file
103
plugins/doc_fragments/kubevirt_vm_options.py
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Copyright: (c) 2018, KubeVirt Team <@kubevirt>
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
|
||||||
|
class ModuleDocFragment(object):
|
||||||
|
|
||||||
|
# Standard oVirt documentation fragment
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
options:
|
||||||
|
disks:
|
||||||
|
description:
|
||||||
|
- List of dictionaries which specify disks of the virtual machine.
|
||||||
|
- "A disk can be made accessible via four different types: I(disk), I(lun), I(cdrom), I(floppy)."
|
||||||
|
- "All possible configuration options are available in U(https://kubevirt.io/api-reference/master/definitions.html#_v1_disk)"
|
||||||
|
- Each disk must have specified a I(volume) that declares which volume type of the disk
|
||||||
|
All possible configuration options of volume are available in U(https://kubevirt.io/api-reference/master/definitions.html#_v1_volume).
|
||||||
|
type: list
|
||||||
|
labels:
|
||||||
|
description:
|
||||||
|
- Labels are key/value pairs that are attached to virtual machines. Labels are intended to be used to
|
||||||
|
specify identifying attributes of virtual machines that are meaningful and relevant to users, but do not directly
|
||||||
|
imply semantics to the core system. Labels can be used to organize and to select subsets of virtual machines.
|
||||||
|
Labels can be attached to virtual machines at creation time and subsequently added and modified at any time.
|
||||||
|
- More on labels that are used for internal implementation U(https://kubevirt.io/user-guide/#/misc/annotations_and_labels)
|
||||||
|
type: dict
|
||||||
|
interfaces:
|
||||||
|
description:
|
||||||
|
- An interface defines a virtual network interface of a virtual machine (also called a frontend).
|
||||||
|
- All possible configuration options interfaces are available in U(https://kubevirt.io/api-reference/master/definitions.html#_v1_interface)
|
||||||
|
- Each interface must have specified a I(network) that declares which logical or physical device it is connected to (also called as backend).
|
||||||
|
All possible configuration options of network are available in U(https://kubevirt.io/api-reference/master/definitions.html#_v1_network).
|
||||||
|
type: list
|
||||||
|
cloud_init_nocloud:
|
||||||
|
description:
|
||||||
|
- "Represents a cloud-init NoCloud user-data source. The NoCloud data will be added
|
||||||
|
as a disk to the virtual machine. A proper cloud-init installation is required inside the guest.
|
||||||
|
More information U(https://kubevirt.io/api-reference/master/definitions.html#_v1_cloudinitnocloudsource)"
|
||||||
|
type: dict
|
||||||
|
affinity:
|
||||||
|
description:
|
||||||
|
- "Describes node affinity scheduling rules for the vm."
|
||||||
|
type: dict
|
||||||
|
suboptions:
|
||||||
|
soft:
|
||||||
|
description:
|
||||||
|
- "The scheduler will prefer to schedule vms to nodes that satisfy the affinity expressions specified by this field, but it may choose a
|
||||||
|
node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for
|
||||||
|
each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute
|
||||||
|
a sum by iterating through the elements of this field and adding C(weight) to the sum if the node has vms which matches the corresponding
|
||||||
|
C(term); the nodes with the highest sum are the most preferred."
|
||||||
|
type: dict
|
||||||
|
hard:
|
||||||
|
description:
|
||||||
|
- "If the affinity requirements specified by this field are not met at scheduling time, the vm will not be scheduled onto the node. If
|
||||||
|
the affinity requirements specified by this field cease to be met at some point during vm execution (e.g. due to a vm label update), the
|
||||||
|
system may or may not try to eventually evict the vm from its node. When there are multiple elements, the lists of nodes corresponding to
|
||||||
|
each C(term) are intersected, i.e. all terms must be satisfied."
|
||||||
|
type: dict
|
||||||
|
node_affinity:
|
||||||
|
description:
|
||||||
|
- "Describes vm affinity scheduling rules e.g. co-locate this vm in the same node, zone, etc. as some other vms"
|
||||||
|
type: dict
|
||||||
|
suboptions:
|
||||||
|
soft:
|
||||||
|
description:
|
||||||
|
- "The scheduler will prefer to schedule vms to nodes that satisfy the affinity expressions specified by this field, but it may choose
|
||||||
|
a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e.
|
||||||
|
for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.),
|
||||||
|
compute a sum by iterating through the elements of this field and adding C(weight) to the sum if the node matches the corresponding
|
||||||
|
match_expressions; the nodes with the highest sum are the most preferred."
|
||||||
|
type: dict
|
||||||
|
hard:
|
||||||
|
description:
|
||||||
|
- "If the affinity requirements specified by this field are not met at scheduling time, the vm will not be scheduled onto the node. If
|
||||||
|
the affinity requirements specified by this field cease to be met at some point during vm execution (e.g. due to an update), the system
|
||||||
|
may or may not try to eventually evict the vm from its node."
|
||||||
|
type: dict
|
||||||
|
anti_affinity:
|
||||||
|
description:
|
||||||
|
- "Describes vm anti-affinity scheduling rules e.g. avoid putting this vm in the same node, zone, etc. as some other vms."
|
||||||
|
type: dict
|
||||||
|
suboptions:
|
||||||
|
soft:
|
||||||
|
description:
|
||||||
|
- "The scheduler will prefer to schedule vms to nodes that satisfy the anti-affinity expressions specified by this field, but it may
|
||||||
|
choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights,
|
||||||
|
i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling anti-affinity expressions,
|
||||||
|
etc.), compute a sum by iterating through the elements of this field and adding C(weight) to the sum if the node has vms which matches
|
||||||
|
the corresponding C(term); the nodes with the highest sum are the most preferred."
|
||||||
|
type: dict
|
||||||
|
hard:
|
||||||
|
description:
|
||||||
|
- "If the anti-affinity requirements specified by this field are not met at scheduling time, the vm will not be scheduled onto the node.
|
||||||
|
If the anti-affinity requirements specified by this field cease to be met at some point during vm execution (e.g. due to a vm label
|
||||||
|
update), the system may or may not try to eventually evict the vm from its node. When there are multiple elements, the lists of nodes
|
||||||
|
corresponding to each C(term) are intersected, i.e. all terms must be satisfied."
|
||||||
|
type: dict
|
||||||
|
'''
|
||||||
@@ -15,7 +15,7 @@ class ModuleDocFragment(object):
|
|||||||
options:
|
options:
|
||||||
bind_dn:
|
bind_dn:
|
||||||
description:
|
description:
|
||||||
- A DN to bind with. If this is omitted, we'll try a SASL bind with the EXTERNAL mechanism as default.
|
- A DN to bind with. If this is omitted, we'll try a SASL bind with the EXTERNAL mechanism.
|
||||||
- If this is blank, we'll use an anonymous bind.
|
- If this is blank, we'll use an anonymous bind.
|
||||||
type: str
|
type: str
|
||||||
bind_pw:
|
bind_pw:
|
||||||
@@ -27,15 +27,6 @@ options:
|
|||||||
description:
|
description:
|
||||||
- The DN of the entry to add or remove.
|
- The DN of the entry to add or remove.
|
||||||
type: str
|
type: str
|
||||||
referrals_chasing:
|
|
||||||
choices: [disabled, anonymous]
|
|
||||||
default: anonymous
|
|
||||||
type: str
|
|
||||||
description:
|
|
||||||
- Set the referrals chasing behavior.
|
|
||||||
- C(anonymous) follow referrals anonymously. This is the default behavior.
|
|
||||||
- C(disabled) disable referrals chasing. This sets C(OPT_REFERRALS) to off.
|
|
||||||
version_added: 2.0.0
|
|
||||||
server_uri:
|
server_uri:
|
||||||
description:
|
description:
|
||||||
- A URI to the LDAP server.
|
- A URI to the LDAP server.
|
||||||
@@ -53,12 +44,4 @@ options:
|
|||||||
- This should only be used on sites using self-signed certificates.
|
- This should only be used on sites using self-signed certificates.
|
||||||
type: bool
|
type: bool
|
||||||
default: yes
|
default: yes
|
||||||
sasl_class:
|
|
||||||
description:
|
|
||||||
- The class to use for SASL authentication.
|
|
||||||
- possible choices are C(external), C(gssapi).
|
|
||||||
type: str
|
|
||||||
choices: ['external', 'gssapi']
|
|
||||||
default: external
|
|
||||||
version_added: "2.0.0"
|
|
||||||
'''
|
'''
|
||||||
|
|||||||
@@ -78,24 +78,6 @@ options:
|
|||||||
variable.
|
variable.
|
||||||
type: int
|
type: int
|
||||||
default: 1000
|
default: 1000
|
||||||
http_pool_connections:
|
|
||||||
description:
|
|
||||||
- Number of pools to be used by the C(infoblox_client.Connector) object.
|
|
||||||
- This is passed as-is to the underlying C(requests.adapters.HTTPAdapter) class.
|
|
||||||
type: int
|
|
||||||
default: 10
|
|
||||||
http_pool_maxsize:
|
|
||||||
description:
|
|
||||||
- Maximum number of connections per pool to be used by the C(infoblox_client.Connector) object.
|
|
||||||
- This is passed as-is to the underlying C(requests.adapters.HTTPAdapter) class.
|
|
||||||
type: int
|
|
||||||
default: 10
|
|
||||||
silent_ssl_warnings:
|
|
||||||
description:
|
|
||||||
- Disable C(urllib3) SSL warnings in the C(infoblox_client.Connector) object.
|
|
||||||
- This is passed as-is to the underlying C(requests.adapters.HTTPAdapter) class.
|
|
||||||
type: bool
|
|
||||||
default: true
|
|
||||||
notes:
|
notes:
|
||||||
- "This module must be run locally, which can be achieved by specifying C(connection: local)."
|
- "This module must be run locally, which can be achieved by specifying C(connection: local)."
|
||||||
- Please read the :ref:`nios_guide` for more detailed information on how to use Infoblox with Ansible.
|
- Please read the :ref:`nios_guide` for more detailed information on how to use Infoblox with Ansible.
|
||||||
|
|||||||
@@ -13,32 +13,12 @@ class ModuleDocFragment(object):
|
|||||||
DOCUMENTATION = r'''
|
DOCUMENTATION = r'''
|
||||||
options:
|
options:
|
||||||
config:
|
config:
|
||||||
description:
|
description:
|
||||||
- Path to a .json configuration file containing the OneView client configuration.
|
- Path to a .json configuration file containing the OneView client configuration.
|
||||||
The configuration file is optional and when used should be present in the host running the ansible commands.
|
The configuration file is optional and when used should be present in the host running the ansible commands.
|
||||||
If the file path is not provided, the configuration will be loaded from environment variables.
|
If the file path is not provided, the configuration will be loaded from environment variables.
|
||||||
For links to example configuration files or how to use the environment variables verify the notes section.
|
For links to example configuration files or how to use the environment variables verify the notes section.
|
||||||
type: path
|
type: path
|
||||||
api_version:
|
|
||||||
description:
|
|
||||||
- OneView API Version.
|
|
||||||
type: int
|
|
||||||
image_streamer_hostname:
|
|
||||||
description:
|
|
||||||
- IP address or hostname for the HPE Image Streamer REST API.
|
|
||||||
type: str
|
|
||||||
hostname:
|
|
||||||
description:
|
|
||||||
- IP address or hostname for the appliance.
|
|
||||||
type: str
|
|
||||||
username:
|
|
||||||
description:
|
|
||||||
- Username for API authentication.
|
|
||||||
type: str
|
|
||||||
password:
|
|
||||||
description:
|
|
||||||
- Password for API authentication.
|
|
||||||
type: str
|
|
||||||
|
|
||||||
requirements:
|
requirements:
|
||||||
- python >= 2.7.9
|
- python >= 2.7.9
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2018, Oracle and/or its affiliates.
|
# Copyright (c) 2018, Oracle and/or its affiliates.
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
@@ -48,7 +47,7 @@ class ModuleDocFragment(object):
|
|||||||
OCI_USER_KEY_FILE variable, if any, is used. This option is required if the private key is
|
OCI_USER_KEY_FILE variable, if any, is used. This option is required if the private key is
|
||||||
not specified through a configuration file (See C(config_file_location)). If the key is encrypted
|
not specified through a configuration file (See C(config_file_location)). If the key is encrypted
|
||||||
with a pass-phrase, the C(api_user_key_pass_phrase) option must also be provided.
|
with a pass-phrase, the C(api_user_key_pass_phrase) option must also be provided.
|
||||||
type: path
|
type: str
|
||||||
api_user_key_pass_phrase:
|
api_user_key_pass_phrase:
|
||||||
description:
|
description:
|
||||||
- Passphrase used by the key referenced in C(api_user_key_file), if it is encrypted. If not set, then
|
- Passphrase used by the key referenced in C(api_user_key_file), if it is encrypted. If not set, then
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2018, Oracle and/or its affiliates.
|
# Copyright (c) 2018, Oracle and/or its affiliates.
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
@@ -21,5 +20,4 @@ class ModuleDocFragment(object):
|
|||||||
identify an instance of the resource. By default, all the attributes of a resource except
|
identify an instance of the resource. By default, all the attributes of a resource except
|
||||||
I(freeform_tags) are used to uniquely identify a resource.
|
I(freeform_tags) are used to uniquely identify a resource.
|
||||||
type: list
|
type: list
|
||||||
elements: str
|
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2018, Oracle and/or its affiliates.
|
# Copyright (c) 2018, Oracle and/or its affiliates.
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2018, Oracle and/or its affiliates.
|
# Copyright (c) 2018, Oracle and/or its affiliates.
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2018, Oracle and/or its affiliates.
|
# Copyright (c) 2018, Oracle and/or its affiliates.
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2018, Oracle and/or its affiliates.
|
# Copyright (c) 2018, Oracle and/or its affiliates.
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
|||||||
62
plugins/doc_fragments/postgres.py
Normal file
62
plugins/doc_fragments/postgres.py
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
|
||||||
|
class ModuleDocFragment(object):
|
||||||
|
# Postgres documentation fragment
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
options:
|
||||||
|
login_user:
|
||||||
|
description:
|
||||||
|
- The username used to authenticate with.
|
||||||
|
type: str
|
||||||
|
default: postgres
|
||||||
|
login_password:
|
||||||
|
description:
|
||||||
|
- The password used to authenticate with.
|
||||||
|
type: str
|
||||||
|
login_host:
|
||||||
|
description:
|
||||||
|
- Host running the database.
|
||||||
|
type: str
|
||||||
|
login_unix_socket:
|
||||||
|
description:
|
||||||
|
- Path to a Unix domain socket for local connections.
|
||||||
|
type: str
|
||||||
|
port:
|
||||||
|
description:
|
||||||
|
- Database port to connect to.
|
||||||
|
type: int
|
||||||
|
default: 5432
|
||||||
|
aliases: [ login_port ]
|
||||||
|
ssl_mode:
|
||||||
|
description:
|
||||||
|
- Determines whether or with what priority a secure SSL TCP/IP connection will be negotiated with the server.
|
||||||
|
- See U(https://www.postgresql.org/docs/current/static/libpq-ssl.html) for more information on the modes.
|
||||||
|
- Default of C(prefer) matches libpq default.
|
||||||
|
type: str
|
||||||
|
default: prefer
|
||||||
|
choices: [ allow, disable, prefer, require, verify-ca, verify-full ]
|
||||||
|
ca_cert:
|
||||||
|
description:
|
||||||
|
- Specifies the name of a file containing SSL certificate authority (CA) certificate(s).
|
||||||
|
- If the file exists, the server's certificate will be verified to be signed by one of these authorities.
|
||||||
|
type: str
|
||||||
|
aliases: [ ssl_rootcert ]
|
||||||
|
notes:
|
||||||
|
- The default authentication assumes that you are either logging in as or sudo'ing to the C(postgres) account on the host.
|
||||||
|
- To avoid "Peer authentication failed for user postgres" error,
|
||||||
|
use postgres user as a I(become_user).
|
||||||
|
- This module uses psycopg2, a Python PostgreSQL database adapter. You must
|
||||||
|
ensure that psycopg2 is installed on the host before using this module.
|
||||||
|
- If the remote host is the PostgreSQL server (which is the default case), then
|
||||||
|
PostgreSQL must also be installed on the remote host.
|
||||||
|
- For Ubuntu-based systems, install the postgresql, libpq-dev, and python-psycopg2 packages
|
||||||
|
on the remote host before using this module.
|
||||||
|
- The ca_cert parameter requires at least Postgres version 8.4 and I(psycopg2) version 2.4.3.
|
||||||
|
requirements: [ psycopg2 ]
|
||||||
|
'''
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Copyright: (c) 2021, Florian Dambrine <android.florian@gmail.com>
|
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
|
|
||||||
from __future__ import absolute_import, division, print_function
|
|
||||||
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
|
|
||||||
class ModuleDocFragment(object):
|
|
||||||
|
|
||||||
DOCUMENTATION = r"""
|
|
||||||
options:
|
|
||||||
pritunl_url:
|
|
||||||
type: str
|
|
||||||
required: true
|
|
||||||
description:
|
|
||||||
- URL and port of the Pritunl server on which the API is enabled.
|
|
||||||
|
|
||||||
pritunl_api_token:
|
|
||||||
type: str
|
|
||||||
required: true
|
|
||||||
description:
|
|
||||||
- API Token of a Pritunl admin user.
|
|
||||||
- It needs to be enabled in Administrators > USERNAME > Enable Token Authentication.
|
|
||||||
|
|
||||||
pritunl_api_secret:
|
|
||||||
type: str
|
|
||||||
required: true
|
|
||||||
description:
|
|
||||||
- API Secret found in Administrators > USERNAME > API Secret.
|
|
||||||
|
|
||||||
validate_certs:
|
|
||||||
type: bool
|
|
||||||
required: false
|
|
||||||
default: true
|
|
||||||
description:
|
|
||||||
- If certificates should be validated or not.
|
|
||||||
- This should never be set to C(false), except if you are very sure that
|
|
||||||
your connection to the server can not be subject to a Man In The Middle
|
|
||||||
attack.
|
|
||||||
"""
|
|
||||||
@@ -42,23 +42,4 @@ options:
|
|||||||
type: bool
|
type: bool
|
||||||
default: no
|
default: no
|
||||||
requirements: [ "proxmoxer", "requests" ]
|
requirements: [ "proxmoxer", "requests" ]
|
||||||
'''
|
|
||||||
|
|
||||||
SELECTION = r'''
|
|
||||||
options:
|
|
||||||
vmid:
|
|
||||||
description:
|
|
||||||
- Specifies the instance ID.
|
|
||||||
- If not set the next available ID will be fetched from ProxmoxAPI.
|
|
||||||
type: int
|
|
||||||
node:
|
|
||||||
description:
|
|
||||||
- Proxmox VE node on which to operate.
|
|
||||||
- Only required for I(state=present).
|
|
||||||
- For every other states it will be autodiscovered.
|
|
||||||
type: str
|
|
||||||
pool:
|
|
||||||
description:
|
|
||||||
- Add the new VM to the specified pool.
|
|
||||||
type: str
|
|
||||||
'''
|
'''
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8 -*-
|
|
||||||
#
|
#
|
||||||
# Copyright: (c) 2019, Sandeep Kasargod <sandeep@vexata.com>
|
# Copyright: (c) 2019, Sandeep Kasargod <sandeep@vexata.com>
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Copyright: (c) 2021, Felix Fontein <felix@fontein.de>
|
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
|
|
||||||
from __future__ import absolute_import, division, print_function
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
|
|
||||||
def dict_filter(sequence):
|
|
||||||
'''Convert a list of tuples to a dictionary.
|
|
||||||
|
|
||||||
Example: ``[[1, 2], ['a', 'b']] | community.general.dict`` results in ``{1: 2, 'a': 'b'}``
|
|
||||||
'''
|
|
||||||
return dict(sequence)
|
|
||||||
|
|
||||||
|
|
||||||
class FilterModule(object):
|
|
||||||
'''Ansible jinja2 filters'''
|
|
||||||
|
|
||||||
def filters(self):
|
|
||||||
return {
|
|
||||||
'dict': dict_filter,
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Copyright: (c) 2021, Andrew Pantuso (@ajpantuso) <ajpantuso@gmail.com>
|
|
||||||
# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com>
|
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
|
|
||||||
from __future__ import absolute_import, division, print_function
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
from ansible.errors import AnsibleFilterError
|
|
||||||
from ansible.module_utils._text import to_native
|
|
||||||
|
|
||||||
from ansible_collections.community.general.plugins.module_utils.csv import (initialize_dialect, read_csv, CSVError,
|
|
||||||
DialectNotAvailableError,
|
|
||||||
CustomDialectFailureError)
|
|
||||||
|
|
||||||
|
|
||||||
def from_csv(data, dialect='excel', fieldnames=None, delimiter=None, skipinitialspace=None, strict=None):
|
|
||||||
|
|
||||||
dialect_params = {
|
|
||||||
"delimiter": delimiter,
|
|
||||||
"skipinitialspace": skipinitialspace,
|
|
||||||
"strict": strict,
|
|
||||||
}
|
|
||||||
|
|
||||||
try:
|
|
||||||
dialect = initialize_dialect(dialect, **dialect_params)
|
|
||||||
except (CustomDialectFailureError, DialectNotAvailableError) as e:
|
|
||||||
raise AnsibleFilterError(to_native(e))
|
|
||||||
|
|
||||||
reader = read_csv(data, dialect, fieldnames)
|
|
||||||
|
|
||||||
data_list = []
|
|
||||||
|
|
||||||
try:
|
|
||||||
for row in reader:
|
|
||||||
data_list.append(row)
|
|
||||||
except CSVError as e:
|
|
||||||
raise AnsibleFilterError("Unable to process file: %s" % to_native(e))
|
|
||||||
|
|
||||||
return data_list
|
|
||||||
|
|
||||||
|
|
||||||
class FilterModule(object):
|
|
||||||
|
|
||||||
def filters(self):
|
|
||||||
return {
|
|
||||||
'from_csv': from_csv
|
|
||||||
}
|
|
||||||
@@ -35,11 +35,9 @@ def json_query(data, expr):
|
|||||||
raise AnsibleError('You need to install "jmespath" prior to running '
|
raise AnsibleError('You need to install "jmespath" prior to running '
|
||||||
'json_query filter')
|
'json_query filter')
|
||||||
|
|
||||||
# Hack to handle Ansible Unsafe text, AnsibleMapping and AnsibleSequence
|
# Hack to handle Ansible String Types
|
||||||
# See issue: https://github.com/ansible-collections/community.general/issues/320
|
# See issue: https://github.com/ansible-collections/community.general/issues/320
|
||||||
jmespath.functions.REVERSE_TYPES_MAP['string'] = jmespath.functions.REVERSE_TYPES_MAP['string'] + ('AnsibleUnicode', 'AnsibleUnsafeText', )
|
jmespath.functions.REVERSE_TYPES_MAP['string'] = jmespath.functions.REVERSE_TYPES_MAP['string'] + ('AnsibleUnicode', 'AnsibleUnsafeText', )
|
||||||
jmespath.functions.REVERSE_TYPES_MAP['array'] = jmespath.functions.REVERSE_TYPES_MAP['array'] + ('AnsibleSequence', )
|
|
||||||
jmespath.functions.REVERSE_TYPES_MAP['object'] = jmespath.functions.REVERSE_TYPES_MAP['object'] + ('AnsibleMapping', )
|
|
||||||
try:
|
try:
|
||||||
return jmespath.search(expr, data)
|
return jmespath.search(expr, data)
|
||||||
except jmespath.exceptions.JMESPathError as e:
|
except jmespath.exceptions.JMESPathError as e:
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2020, Vladimir Botka <vbotka@gmail.com>
|
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
|
|
||||||
from __future__ import (absolute_import, division, print_function)
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
from ansible.errors import AnsibleError, AnsibleFilterError
|
|
||||||
from ansible.module_utils.six import string_types
|
|
||||||
from ansible.module_utils.common._collections_compat import Mapping, Sequence
|
|
||||||
from collections import defaultdict
|
|
||||||
from operator import itemgetter
|
|
||||||
|
|
||||||
|
|
||||||
def lists_mergeby(l1, l2, index):
|
|
||||||
''' merge lists by attribute index. Example:
|
|
||||||
- debug: msg="{{ l1|community.general.lists_mergeby(l2, 'index')|list }}" '''
|
|
||||||
|
|
||||||
if not isinstance(l1, Sequence):
|
|
||||||
raise AnsibleFilterError('First argument for community.general.lists_mergeby must be list. %s is %s' %
|
|
||||||
(l1, type(l1)))
|
|
||||||
|
|
||||||
if not isinstance(l2, Sequence):
|
|
||||||
raise AnsibleFilterError('Second argument for community.general.lists_mergeby must be list. %s is %s' %
|
|
||||||
(l2, type(l2)))
|
|
||||||
|
|
||||||
if not isinstance(index, string_types):
|
|
||||||
raise AnsibleFilterError('Third argument for community.general.lists_mergeby must be string. %s is %s' %
|
|
||||||
(index, type(index)))
|
|
||||||
|
|
||||||
d = defaultdict(dict)
|
|
||||||
for l in (l1, l2):
|
|
||||||
for elem in l:
|
|
||||||
if not isinstance(elem, Mapping):
|
|
||||||
raise AnsibleFilterError('Elements of list arguments for lists_mergeby must be dictionaries. Found {0!r}.'.format(elem))
|
|
||||||
if index in elem.keys():
|
|
||||||
d[elem[index]].update(elem)
|
|
||||||
return sorted(d.values(), key=itemgetter(index))
|
|
||||||
|
|
||||||
|
|
||||||
class FilterModule(object):
|
|
||||||
''' Ansible list filters '''
|
|
||||||
|
|
||||||
def filters(self):
|
|
||||||
return {
|
|
||||||
'lists_mergeby': lists_mergeby,
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Copyright: (c) 2020-2021, Felix Fontein <felix@fontein.de>
|
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
|
|
||||||
from __future__ import absolute_import, division, print_function
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
|
|
||||||
import os.path
|
|
||||||
|
|
||||||
|
|
||||||
def path_join(list):
|
|
||||||
'''Join list of paths.
|
|
||||||
|
|
||||||
This is a minimal shim for ansible.builtin.path_join included in ansible-base 2.10.
|
|
||||||
This should only be called by Ansible 2.9 or earlier. See meta/runtime.yml for details.
|
|
||||||
'''
|
|
||||||
return os.path.join(*list)
|
|
||||||
|
|
||||||
|
|
||||||
class FilterModule(object):
|
|
||||||
'''Ansible jinja2 filters'''
|
|
||||||
|
|
||||||
def filters(self):
|
|
||||||
return {
|
|
||||||
'path_join': path_join,
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
# Copyright (C) 2021 Eric Lavarde <elavarde@redhat.com>
|
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
|
|
||||||
from __future__ import (absolute_import, division, print_function)
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
from distutils.version import LooseVersion
|
|
||||||
|
|
||||||
|
|
||||||
def version_sort(value, reverse=False):
|
|
||||||
'''Sort a list according to loose versions so that e.g. 2.9 is smaller than 2.10'''
|
|
||||||
return sorted(value, key=LooseVersion, reverse=reverse)
|
|
||||||
|
|
||||||
|
|
||||||
class FilterModule(object):
|
|
||||||
''' Version sort filter '''
|
|
||||||
|
|
||||||
def filters(self):
|
|
||||||
return {
|
|
||||||
'version_sort': version_sort
|
|
||||||
}
|
|
||||||
@@ -8,6 +8,7 @@ __metaclass__ = type
|
|||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
author: Orion Poplawski (@opoplawski)
|
author: Orion Poplawski (@opoplawski)
|
||||||
name: cobbler
|
name: cobbler
|
||||||
|
plugin_type: inventory
|
||||||
short_description: Cobbler inventory source
|
short_description: Cobbler inventory source
|
||||||
version_added: 1.0.0
|
version_added: 1.0.0
|
||||||
description:
|
description:
|
||||||
|
|||||||
272
plugins/inventory/docker_machine.py
Normal file
272
plugins/inventory/docker_machine.py
Normal file
@@ -0,0 +1,272 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2019, Ximon Eighteen <ximon.eighteen@gmail.com>
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
DOCUMENTATION = '''
|
||||||
|
name: docker_machine
|
||||||
|
plugin_type: inventory
|
||||||
|
author: Ximon Eighteen (@ximon18)
|
||||||
|
short_description: Docker Machine inventory source
|
||||||
|
requirements:
|
||||||
|
- L(Docker Machine,https://docs.docker.com/machine/)
|
||||||
|
extends_documentation_fragment:
|
||||||
|
- constructed
|
||||||
|
description:
|
||||||
|
- Get inventory hosts from Docker Machine.
|
||||||
|
- Uses a YAML configuration file that ends with docker_machine.(yml|yaml).
|
||||||
|
- The plugin sets standard host variables C(ansible_host), C(ansible_port), C(ansible_user) and C(ansible_ssh_private_key).
|
||||||
|
- The plugin stores the Docker Machine 'env' output variables in I(dm_) prefixed host variables.
|
||||||
|
|
||||||
|
options:
|
||||||
|
plugin:
|
||||||
|
description: token that ensures this is a source file for the C(docker_machine) plugin.
|
||||||
|
required: yes
|
||||||
|
choices: ['docker_machine', 'community.general.docker_machine']
|
||||||
|
daemon_env:
|
||||||
|
description:
|
||||||
|
- Whether docker daemon connection environment variables should be fetched, and how to behave if they cannot be fetched.
|
||||||
|
- With C(require) and C(require-silently), fetch them and skip any host for which they cannot be fetched.
|
||||||
|
A warning will be issued for any skipped host if the choice is C(require).
|
||||||
|
- With C(optional) and C(optional-silently), fetch them and not skip hosts for which they cannot be fetched.
|
||||||
|
A warning will be issued for hosts where they cannot be fetched if the choice is C(optional).
|
||||||
|
- With C(skip), do not attempt to fetch the docker daemon connection environment variables.
|
||||||
|
- If fetched successfully, the variables will be prefixed with I(dm_) and stored as host variables.
|
||||||
|
type: str
|
||||||
|
choices:
|
||||||
|
- require
|
||||||
|
- require-silently
|
||||||
|
- optional
|
||||||
|
- optional-silently
|
||||||
|
- skip
|
||||||
|
default: require
|
||||||
|
running_required:
|
||||||
|
description: when true, hosts which Docker Machine indicates are in a state other than C(running) will be skipped.
|
||||||
|
type: bool
|
||||||
|
default: yes
|
||||||
|
verbose_output:
|
||||||
|
description: when true, include all available nodes metadata (e.g. Image, Region, Size) as a JSON object named C(docker_machine_node_attributes).
|
||||||
|
type: bool
|
||||||
|
default: yes
|
||||||
|
'''
|
||||||
|
|
||||||
|
EXAMPLES = '''
|
||||||
|
# Minimal example
|
||||||
|
plugin: community.general.docker_machine
|
||||||
|
|
||||||
|
# Example using constructed features to create a group per Docker Machine driver
|
||||||
|
# (https://docs.docker.com/machine/drivers/), e.g.:
|
||||||
|
# $ docker-machine create --driver digitalocean ... mymachine
|
||||||
|
# $ ansible-inventory -i ./path/to/docker-machine.yml --host=mymachine
|
||||||
|
# {
|
||||||
|
# ...
|
||||||
|
# "digitalocean": {
|
||||||
|
# "hosts": [
|
||||||
|
# "mymachine"
|
||||||
|
# ]
|
||||||
|
# ...
|
||||||
|
# }
|
||||||
|
strict: no
|
||||||
|
keyed_groups:
|
||||||
|
- separator: ''
|
||||||
|
key: docker_machine_node_attributes.DriverName
|
||||||
|
|
||||||
|
# Example grouping hosts by Digital Machine tag
|
||||||
|
strict: no
|
||||||
|
keyed_groups:
|
||||||
|
- prefix: tag
|
||||||
|
key: 'dm_tags'
|
||||||
|
|
||||||
|
# Example using compose to override the default SSH behaviour of asking the user to accept the remote host key
|
||||||
|
compose:
|
||||||
|
ansible_ssh_common_args: '"-o StrictHostKeyChecking=accept-new"'
|
||||||
|
'''
|
||||||
|
|
||||||
|
from ansible.errors import AnsibleError
|
||||||
|
from ansible.module_utils._text import to_native
|
||||||
|
from ansible.module_utils._text import to_text
|
||||||
|
from ansible.module_utils.common.process import get_bin_path
|
||||||
|
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
|
||||||
|
from ansible.utils.display import Display
|
||||||
|
|
||||||
|
import json
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
display = Display()
|
||||||
|
|
||||||
|
|
||||||
|
class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
|
''' Host inventory parser for ansible using Docker machine as source. '''
|
||||||
|
|
||||||
|
NAME = 'community.general.docker_machine'
|
||||||
|
|
||||||
|
DOCKER_MACHINE_PATH = None
|
||||||
|
|
||||||
|
def _run_command(self, args):
|
||||||
|
if not self.DOCKER_MACHINE_PATH:
|
||||||
|
try:
|
||||||
|
self.DOCKER_MACHINE_PATH = get_bin_path('docker-machine')
|
||||||
|
except ValueError as e:
|
||||||
|
raise AnsibleError(to_native(e))
|
||||||
|
|
||||||
|
command = [self.DOCKER_MACHINE_PATH]
|
||||||
|
command.extend(args)
|
||||||
|
display.debug('Executing command {0}'.format(command))
|
||||||
|
try:
|
||||||
|
result = subprocess.check_output(command)
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
display.warning('Exception {0} caught while executing command {1}, this was the original exception: {2}'.format(type(e).__name__, command, e))
|
||||||
|
raise e
|
||||||
|
|
||||||
|
return to_text(result).strip()
|
||||||
|
|
||||||
|
def _get_docker_daemon_variables(self, machine_name):
|
||||||
|
'''
|
||||||
|
Capture settings from Docker Machine that would be needed to connect to the remote Docker daemon installed on
|
||||||
|
the Docker Machine remote host. Note: passing '--shell=sh' is a workaround for 'Error: Unknown shell'.
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
env_lines = self._run_command(['env', '--shell=sh', machine_name]).splitlines()
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
# This can happen when the machine is created but provisioning is incomplete
|
||||||
|
return []
|
||||||
|
|
||||||
|
# example output of docker-machine env --shell=sh:
|
||||||
|
# export DOCKER_TLS_VERIFY="1"
|
||||||
|
# export DOCKER_HOST="tcp://134.209.204.160:2376"
|
||||||
|
# export DOCKER_CERT_PATH="/root/.docker/machine/machines/routinator"
|
||||||
|
# export DOCKER_MACHINE_NAME="routinator"
|
||||||
|
# # Run this command to configure your shell:
|
||||||
|
# # eval $(docker-machine env --shell=bash routinator)
|
||||||
|
|
||||||
|
# capture any of the DOCKER_xxx variables that were output and create Ansible host vars
|
||||||
|
# with the same name and value but with a dm_ name prefix.
|
||||||
|
vars = []
|
||||||
|
for line in env_lines:
|
||||||
|
match = re.search('(DOCKER_[^=]+)="([^"]+)"', line)
|
||||||
|
if match:
|
||||||
|
env_var_name = match.group(1)
|
||||||
|
env_var_value = match.group(2)
|
||||||
|
vars.append((env_var_name, env_var_value))
|
||||||
|
|
||||||
|
return vars
|
||||||
|
|
||||||
|
def _get_machine_names(self):
|
||||||
|
# Filter out machines that are not in the Running state as we probably can't do anything useful actions
|
||||||
|
# with them.
|
||||||
|
ls_command = ['ls', '-q']
|
||||||
|
if self.get_option('running_required'):
|
||||||
|
ls_command.extend(['--filter', 'state=Running'])
|
||||||
|
|
||||||
|
try:
|
||||||
|
ls_lines = self._run_command(ls_command)
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
return []
|
||||||
|
|
||||||
|
return ls_lines.splitlines()
|
||||||
|
|
||||||
|
def _inspect_docker_machine_host(self, node):
|
||||||
|
try:
|
||||||
|
inspect_lines = self._run_command(['inspect', self.node])
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return json.loads(inspect_lines)
|
||||||
|
|
||||||
|
def _ip_addr_docker_machine_host(self, node):
|
||||||
|
try:
|
||||||
|
ip_addr = self._run_command(['ip', self.node])
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return ip_addr
|
||||||
|
|
||||||
|
def _should_skip_host(self, machine_name, env_var_tuples, daemon_env):
|
||||||
|
if not env_var_tuples:
|
||||||
|
warning_prefix = 'Unable to fetch Docker daemon env vars from Docker Machine for host {0}'.format(machine_name)
|
||||||
|
if daemon_env in ('require', 'require-silently'):
|
||||||
|
if daemon_env == 'require':
|
||||||
|
display.warning('{0}: host will be skipped'.format(warning_prefix))
|
||||||
|
return True
|
||||||
|
else: # 'optional', 'optional-silently'
|
||||||
|
if daemon_env == 'optional':
|
||||||
|
display.warning('{0}: host will lack dm_DOCKER_xxx variables'.format(warning_prefix))
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _populate(self):
|
||||||
|
daemon_env = self.get_option('daemon_env')
|
||||||
|
try:
|
||||||
|
for self.node in self._get_machine_names():
|
||||||
|
self.node_attrs = self._inspect_docker_machine_host(self.node)
|
||||||
|
if not self.node_attrs:
|
||||||
|
continue
|
||||||
|
|
||||||
|
machine_name = self.node_attrs['Driver']['MachineName']
|
||||||
|
|
||||||
|
# query `docker-machine env` to obtain remote Docker daemon connection settings in the form of commands
|
||||||
|
# that could be used to set environment variables to influence a local Docker client:
|
||||||
|
if daemon_env == 'skip':
|
||||||
|
env_var_tuples = []
|
||||||
|
else:
|
||||||
|
env_var_tuples = self._get_docker_daemon_variables(machine_name)
|
||||||
|
if self._should_skip_host(machine_name, env_var_tuples, daemon_env):
|
||||||
|
continue
|
||||||
|
|
||||||
|
# add an entry in the inventory for this host
|
||||||
|
self.inventory.add_host(machine_name)
|
||||||
|
|
||||||
|
# check for valid ip address from inspect output, else explicitly use ip command to find host ip address
|
||||||
|
# this works around an issue seen with Google Compute Platform where the IP address was not available
|
||||||
|
# via the 'inspect' subcommand but was via the 'ip' subcomannd.
|
||||||
|
if self.node_attrs['Driver']['IPAddress']:
|
||||||
|
ip_addr = self.node_attrs['Driver']['IPAddress']
|
||||||
|
else:
|
||||||
|
ip_addr = self._ip_addr_docker_machine_host(self.node)
|
||||||
|
|
||||||
|
# set standard Ansible remote host connection settings to details captured from `docker-machine`
|
||||||
|
# see: https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html
|
||||||
|
self.inventory.set_variable(machine_name, 'ansible_host', ip_addr)
|
||||||
|
self.inventory.set_variable(machine_name, 'ansible_port', self.node_attrs['Driver']['SSHPort'])
|
||||||
|
self.inventory.set_variable(machine_name, 'ansible_user', self.node_attrs['Driver']['SSHUser'])
|
||||||
|
self.inventory.set_variable(machine_name, 'ansible_ssh_private_key_file', self.node_attrs['Driver']['SSHKeyPath'])
|
||||||
|
|
||||||
|
# set variables based on Docker Machine tags
|
||||||
|
tags = self.node_attrs['Driver'].get('Tags') or ''
|
||||||
|
self.inventory.set_variable(machine_name, 'dm_tags', tags)
|
||||||
|
|
||||||
|
# set variables based on Docker Machine env variables
|
||||||
|
for kv in env_var_tuples:
|
||||||
|
self.inventory.set_variable(machine_name, 'dm_{0}'.format(kv[0]), kv[1])
|
||||||
|
|
||||||
|
if self.get_option('verbose_output'):
|
||||||
|
self.inventory.set_variable(machine_name, 'docker_machine_node_attributes', self.node_attrs)
|
||||||
|
|
||||||
|
# Use constructed if applicable
|
||||||
|
strict = self.get_option('strict')
|
||||||
|
|
||||||
|
# Composed variables
|
||||||
|
self._set_composite_vars(self.get_option('compose'), self.node_attrs, machine_name, strict=strict)
|
||||||
|
|
||||||
|
# Complex groups based on jinja2 conditionals, hosts that meet the conditional are added to group
|
||||||
|
self._add_host_to_composed_groups(self.get_option('groups'), self.node_attrs, machine_name, strict=strict)
|
||||||
|
|
||||||
|
# Create groups based on variable values and add the corresponding hosts to it
|
||||||
|
self._add_host_to_keyed_groups(self.get_option('keyed_groups'), self.node_attrs, machine_name, strict=strict)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
raise AnsibleError('Unable to fetch hosts from Docker Machine, this was the original exception: %s' %
|
||||||
|
to_native(e), orig_exc=e)
|
||||||
|
|
||||||
|
def verify_file(self, path):
|
||||||
|
"""Return the possibility of a file being consumable by this plugin."""
|
||||||
|
return (
|
||||||
|
super(InventoryModule, self).verify_file(path) and
|
||||||
|
path.endswith(('docker_machine.yaml', 'docker_machine.yml')))
|
||||||
|
|
||||||
|
def parse(self, inventory, loader, path, cache=True):
|
||||||
|
super(InventoryModule, self).parse(inventory, loader, path, cache)
|
||||||
|
self._read_config_data(path)
|
||||||
|
self._populate()
|
||||||
255
plugins/inventory/docker_swarm.py
Normal file
255
plugins/inventory/docker_swarm.py
Normal file
@@ -0,0 +1,255 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2018, Stefan Heitmueller <stefan.heitmueller@gmx.com>
|
||||||
|
# Copyright (c) 2018 Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
DOCUMENTATION = '''
|
||||||
|
name: docker_swarm
|
||||||
|
plugin_type: inventory
|
||||||
|
author:
|
||||||
|
- Stefan Heitmüller (@morph027) <stefan.heitmueller@gmx.com>
|
||||||
|
short_description: Ansible dynamic inventory plugin for Docker swarm nodes.
|
||||||
|
requirements:
|
||||||
|
- python >= 2.7
|
||||||
|
- L(Docker SDK for Python,https://docker-py.readthedocs.io/en/stable/) >= 1.10.0
|
||||||
|
extends_documentation_fragment:
|
||||||
|
- constructed
|
||||||
|
description:
|
||||||
|
- Reads inventories from the Docker swarm API.
|
||||||
|
- Uses a YAML configuration file docker_swarm.[yml|yaml].
|
||||||
|
- "The plugin returns following groups of swarm nodes: I(all) - all hosts; I(workers) - all worker nodes;
|
||||||
|
I(managers) - all manager nodes; I(leader) - the swarm leader node;
|
||||||
|
I(nonleaders) - all nodes except the swarm leader."
|
||||||
|
options:
|
||||||
|
plugin:
|
||||||
|
description: The name of this plugin, it should always be set to C(community.general.docker_swarm)
|
||||||
|
for this plugin to recognize it as it's own.
|
||||||
|
type: str
|
||||||
|
required: true
|
||||||
|
choices: [ docker_swarm, community.general.docker_swarm ]
|
||||||
|
docker_host:
|
||||||
|
description:
|
||||||
|
- Socket of a Docker swarm manager node (C(tcp), C(unix)).
|
||||||
|
- "Use C(unix://var/run/docker.sock) to connect via local socket."
|
||||||
|
type: str
|
||||||
|
required: true
|
||||||
|
aliases: [ docker_url ]
|
||||||
|
verbose_output:
|
||||||
|
description: Toggle to (not) include all available nodes metadata (e.g. C(Platform), C(Architecture), C(OS),
|
||||||
|
C(EngineVersion))
|
||||||
|
type: bool
|
||||||
|
default: yes
|
||||||
|
tls:
|
||||||
|
description: Connect using TLS without verifying the authenticity of the Docker host server.
|
||||||
|
type: bool
|
||||||
|
default: no
|
||||||
|
validate_certs:
|
||||||
|
description: Toggle if connecting using TLS with or without verifying the authenticity of the Docker
|
||||||
|
host server.
|
||||||
|
type: bool
|
||||||
|
default: no
|
||||||
|
aliases: [ tls_verify ]
|
||||||
|
client_key:
|
||||||
|
description: Path to the client's TLS key file.
|
||||||
|
type: path
|
||||||
|
aliases: [ tls_client_key, key_path ]
|
||||||
|
ca_cert:
|
||||||
|
description: Use a CA certificate when performing server verification by providing the path to a CA
|
||||||
|
certificate file.
|
||||||
|
type: path
|
||||||
|
aliases: [ tls_ca_cert, cacert_path ]
|
||||||
|
client_cert:
|
||||||
|
description: Path to the client's TLS certificate file.
|
||||||
|
type: path
|
||||||
|
aliases: [ tls_client_cert, cert_path ]
|
||||||
|
tls_hostname:
|
||||||
|
description: When verifying the authenticity of the Docker host server, provide the expected name of
|
||||||
|
the server.
|
||||||
|
type: str
|
||||||
|
ssl_version:
|
||||||
|
description: Provide a valid SSL version number. Default value determined by ssl.py module.
|
||||||
|
type: str
|
||||||
|
api_version:
|
||||||
|
description:
|
||||||
|
- The version of the Docker API running on the Docker Host.
|
||||||
|
- Defaults to the latest version of the API supported by docker-py.
|
||||||
|
type: str
|
||||||
|
aliases: [ docker_api_version ]
|
||||||
|
timeout:
|
||||||
|
description:
|
||||||
|
- The maximum amount of time in seconds to wait on a response from the API.
|
||||||
|
- If the value is not specified in the task, the value of environment variable C(DOCKER_TIMEOUT)
|
||||||
|
will be used instead. If the environment variable is not set, the default value will be used.
|
||||||
|
type: int
|
||||||
|
default: 60
|
||||||
|
aliases: [ time_out ]
|
||||||
|
include_host_uri:
|
||||||
|
description: Toggle to return the additional attribute C(ansible_host_uri) which contains the URI of the
|
||||||
|
swarm leader in format of C(tcp://172.16.0.1:2376). This value may be used without additional
|
||||||
|
modification as value of option I(docker_host) in Docker Swarm modules when connecting via API.
|
||||||
|
The port always defaults to C(2376).
|
||||||
|
type: bool
|
||||||
|
default: no
|
||||||
|
include_host_uri_port:
|
||||||
|
description: Override the detected port number included in I(ansible_host_uri)
|
||||||
|
type: int
|
||||||
|
'''
|
||||||
|
|
||||||
|
EXAMPLES = '''
|
||||||
|
# Minimal example using local docker
|
||||||
|
plugin: community.general.docker_swarm
|
||||||
|
docker_host: unix://var/run/docker.sock
|
||||||
|
|
||||||
|
# Minimal example using remote docker
|
||||||
|
plugin: community.general.docker_swarm
|
||||||
|
docker_host: tcp://my-docker-host:2375
|
||||||
|
|
||||||
|
# Example using remote docker with unverified TLS
|
||||||
|
plugin: community.general.docker_swarm
|
||||||
|
docker_host: tcp://my-docker-host:2376
|
||||||
|
tls: yes
|
||||||
|
|
||||||
|
# Example using remote docker with verified TLS and client certificate verification
|
||||||
|
plugin: community.general.docker_swarm
|
||||||
|
docker_host: tcp://my-docker-host:2376
|
||||||
|
validate_certs: yes
|
||||||
|
ca_cert: /somewhere/ca.pem
|
||||||
|
client_key: /somewhere/key.pem
|
||||||
|
client_cert: /somewhere/cert.pem
|
||||||
|
|
||||||
|
# Example using constructed features to create groups and set ansible_host
|
||||||
|
plugin: community.general.docker_swarm
|
||||||
|
docker_host: tcp://my-docker-host:2375
|
||||||
|
strict: False
|
||||||
|
keyed_groups:
|
||||||
|
# add e.g. x86_64 hosts to an arch_x86_64 group
|
||||||
|
- prefix: arch
|
||||||
|
key: 'Description.Platform.Architecture'
|
||||||
|
# add e.g. linux hosts to an os_linux group
|
||||||
|
- prefix: os
|
||||||
|
key: 'Description.Platform.OS'
|
||||||
|
# create a group per node label
|
||||||
|
# e.g. a node labeled w/ "production" ends up in group "label_production"
|
||||||
|
# hint: labels containing special characters will be converted to safe names
|
||||||
|
- key: 'Spec.Labels'
|
||||||
|
prefix: label
|
||||||
|
'''
|
||||||
|
|
||||||
|
from ansible.errors import AnsibleError
|
||||||
|
from ansible.module_utils._text import to_native
|
||||||
|
from ansible_collections.community.general.plugins.module_utils.docker.common import update_tls_hostname, get_connect_params
|
||||||
|
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
|
||||||
|
from ansible.parsing.utils.addresses import parse_address
|
||||||
|
|
||||||
|
try:
|
||||||
|
import docker
|
||||||
|
HAS_DOCKER = True
|
||||||
|
except ImportError:
|
||||||
|
HAS_DOCKER = False
|
||||||
|
|
||||||
|
|
||||||
|
class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||||
|
''' Host inventory parser for ansible using Docker swarm as source. '''
|
||||||
|
|
||||||
|
NAME = 'community.general.docker_swarm'
|
||||||
|
|
||||||
|
def _fail(self, msg):
|
||||||
|
raise AnsibleError(msg)
|
||||||
|
|
||||||
|
def _populate(self):
|
||||||
|
raw_params = dict(
|
||||||
|
docker_host=self.get_option('docker_host'),
|
||||||
|
tls=self.get_option('tls'),
|
||||||
|
tls_verify=self.get_option('validate_certs'),
|
||||||
|
key_path=self.get_option('client_key'),
|
||||||
|
cacert_path=self.get_option('ca_cert'),
|
||||||
|
cert_path=self.get_option('client_cert'),
|
||||||
|
tls_hostname=self.get_option('tls_hostname'),
|
||||||
|
api_version=self.get_option('api_version'),
|
||||||
|
timeout=self.get_option('timeout'),
|
||||||
|
ssl_version=self.get_option('ssl_version'),
|
||||||
|
debug=None,
|
||||||
|
)
|
||||||
|
update_tls_hostname(raw_params)
|
||||||
|
connect_params = get_connect_params(raw_params, fail_function=self._fail)
|
||||||
|
self.client = docker.DockerClient(**connect_params)
|
||||||
|
self.inventory.add_group('all')
|
||||||
|
self.inventory.add_group('manager')
|
||||||
|
self.inventory.add_group('worker')
|
||||||
|
self.inventory.add_group('leader')
|
||||||
|
self.inventory.add_group('nonleaders')
|
||||||
|
|
||||||
|
if self.get_option('include_host_uri'):
|
||||||
|
if self.get_option('include_host_uri_port'):
|
||||||
|
host_uri_port = str(self.get_option('include_host_uri_port'))
|
||||||
|
elif self.get_option('tls') or self.get_option('validate_certs'):
|
||||||
|
host_uri_port = '2376'
|
||||||
|
else:
|
||||||
|
host_uri_port = '2375'
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.nodes = self.client.nodes.list()
|
||||||
|
for self.node in self.nodes:
|
||||||
|
self.node_attrs = self.client.nodes.get(self.node.id).attrs
|
||||||
|
self.inventory.add_host(self.node_attrs['ID'])
|
||||||
|
self.inventory.add_host(self.node_attrs['ID'], group=self.node_attrs['Spec']['Role'])
|
||||||
|
self.inventory.set_variable(self.node_attrs['ID'], 'ansible_host',
|
||||||
|
self.node_attrs['Status']['Addr'])
|
||||||
|
if self.get_option('include_host_uri'):
|
||||||
|
self.inventory.set_variable(self.node_attrs['ID'], 'ansible_host_uri',
|
||||||
|
'tcp://' + self.node_attrs['Status']['Addr'] + ':' + host_uri_port)
|
||||||
|
if self.get_option('verbose_output'):
|
||||||
|
self.inventory.set_variable(self.node_attrs['ID'], 'docker_swarm_node_attributes', self.node_attrs)
|
||||||
|
if 'ManagerStatus' in self.node_attrs:
|
||||||
|
if self.node_attrs['ManagerStatus'].get('Leader'):
|
||||||
|
# This is workaround of bug in Docker when in some cases the Leader IP is 0.0.0.0
|
||||||
|
# Check moby/moby#35437 for details
|
||||||
|
swarm_leader_ip = parse_address(self.node_attrs['ManagerStatus']['Addr'])[0] or \
|
||||||
|
self.node_attrs['Status']['Addr']
|
||||||
|
if self.get_option('include_host_uri'):
|
||||||
|
self.inventory.set_variable(self.node_attrs['ID'], 'ansible_host_uri',
|
||||||
|
'tcp://' + swarm_leader_ip + ':' + host_uri_port)
|
||||||
|
self.inventory.set_variable(self.node_attrs['ID'], 'ansible_host', swarm_leader_ip)
|
||||||
|
self.inventory.add_host(self.node_attrs['ID'], group='leader')
|
||||||
|
else:
|
||||||
|
self.inventory.add_host(self.node_attrs['ID'], group='nonleaders')
|
||||||
|
else:
|
||||||
|
self.inventory.add_host(self.node_attrs['ID'], group='nonleaders')
|
||||||
|
# Use constructed if applicable
|
||||||
|
strict = self.get_option('strict')
|
||||||
|
# Composed variables
|
||||||
|
self._set_composite_vars(self.get_option('compose'),
|
||||||
|
self.node_attrs,
|
||||||
|
self.node_attrs['ID'],
|
||||||
|
strict=strict)
|
||||||
|
# Complex groups based on jinja2 conditionals, hosts that meet the conditional are added to group
|
||||||
|
self._add_host_to_composed_groups(self.get_option('groups'),
|
||||||
|
self.node_attrs,
|
||||||
|
self.node_attrs['ID'],
|
||||||
|
strict=strict)
|
||||||
|
# Create groups based on variable values and add the corresponding hosts to it
|
||||||
|
self._add_host_to_keyed_groups(self.get_option('keyed_groups'),
|
||||||
|
self.node_attrs,
|
||||||
|
self.node_attrs['ID'],
|
||||||
|
strict=strict)
|
||||||
|
except Exception as e:
|
||||||
|
raise AnsibleError('Unable to fetch hosts from Docker swarm API, this was the original exception: %s' %
|
||||||
|
to_native(e))
|
||||||
|
|
||||||
|
def verify_file(self, path):
|
||||||
|
"""Return the possibly of a file being consumable by this plugin."""
|
||||||
|
return (
|
||||||
|
super(InventoryModule, self).verify_file(path) and
|
||||||
|
path.endswith(('docker_swarm.yaml', 'docker_swarm.yml')))
|
||||||
|
|
||||||
|
def parse(self, inventory, loader, path, cache=True):
|
||||||
|
if not HAS_DOCKER:
|
||||||
|
raise AnsibleError('The Docker swarm dynamic inventory plugin requires the Docker SDK for Python: '
|
||||||
|
'https://github.com/docker/docker-py.')
|
||||||
|
super(InventoryModule, self).parse(inventory, loader, path, cache)
|
||||||
|
self._read_config_data(path)
|
||||||
|
self._populate()
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user