rundeck 0.0.3.pre → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +10 -0
  3. data/.rubocop_todo.yml +0 -10
  4. data/.travis.yml +1 -1
  5. data/lib/rundeck/client.rb +61 -3
  6. data/lib/rundeck/client/execution.rb +194 -0
  7. data/lib/rundeck/client/{jobs.rb → job.rb} +19 -36
  8. data/lib/rundeck/client/{keys.rb → key.rb} +42 -20
  9. data/lib/rundeck/configuration.rb +5 -1
  10. data/lib/rundeck/objectified_hash.rb +13 -3
  11. data/lib/rundeck/request.rb +7 -1
  12. data/lib/rundeck/version.rb +1 -1
  13. data/rundeck.gemspec +2 -1
  14. data/spec/cassettes/12/abort_execution_not_running.yml +41 -0
  15. data/spec/cassettes/12/abort_execution_valid.yml +41 -0
  16. data/spec/cassettes/12/abort_executions_invalid.yml +41 -0
  17. data/spec/cassettes/12/bulk_delete_executions_invalid.yml +46 -0
  18. data/spec/cassettes/12/bulk_delete_executions_valid.yml +41 -0
  19. data/spec/cassettes/12/create_private_key.yml +64 -0
  20. data/spec/cassettes/12/create_public_key.yml +38 -0
  21. data/spec/cassettes/12/delete_execution_invalid.yml +41 -0
  22. data/spec/cassettes/12/delete_execution_valid.yml +32 -0
  23. data/spec/cassettes/12/delete_job_executions.yml +41 -0
  24. data/spec/cassettes/12/delete_job_executions_invalid.yml +41 -0
  25. data/spec/cassettes/12/delete_job_invalid.yml +41 -0
  26. data/spec/cassettes/12/delete_job_valid.yml +32 -0
  27. data/spec/cassettes/12/delete_key_invalid.yml +41 -0
  28. data/spec/cassettes/12/delete_key_private.yml +32 -0
  29. data/spec/cassettes/12/delete_key_public.yml +32 -0
  30. data/spec/cassettes/12/execution_invalid.yml +41 -0
  31. data/spec/cassettes/12/execution_query_invalid.yml +39 -0
  32. data/spec/cassettes/12/execution_query_no_params_valid.yml +124 -0
  33. data/spec/cassettes/12/execution_state_invalid.yml +41 -0
  34. data/spec/cassettes/12/execution_state_valid.yml +39 -0
  35. data/spec/cassettes/12/execution_valid.yml +60 -0
  36. data/spec/cassettes/12/export_job_xml.yml +234 -0
  37. data/spec/cassettes/12/export_job_yaml.yml +228 -0
  38. data/spec/cassettes/12/import_job_xml.yml +69 -0
  39. data/spec/cassettes/12/import_job_yaml.yml +63 -0
  40. data/spec/cassettes/12/job.yml +84 -0
  41. data/spec/cassettes/12/job_executions.yml +96 -0
  42. data/spec/cassettes/12/jobs.yml +76 -0
  43. data/spec/cassettes/12/key_contents_direct.yml +67 -0
  44. data/spec/cassettes/12/key_contents_multiple.yml +38 -0
  45. data/spec/cassettes/12/key_contents_private.yml +35 -0
  46. data/spec/cassettes/12/key_metadata_direct.yml +35 -0
  47. data/spec/cassettes/12/key_metadata_multiple.yml +38 -0
  48. data/spec/cassettes/12/keys_direct.yml +35 -0
  49. data/spec/cassettes/12/keys_multiple.yml +38 -0
  50. data/spec/cassettes/12/keys_none.yml +34 -0
  51. data/spec/cassettes/12/run_job_invalid.yml +44 -0
  52. data/spec/cassettes/12/run_job_valid.yml +77 -0
  53. data/spec/cassettes/12/running_jobs_multiple.yml +70 -0
  54. data/spec/cassettes/12/running_jobs_none.yml +39 -0
  55. data/spec/cassettes/12/running_jobs_single.yml +55 -0
  56. data/spec/cassettes/12/update_private_key.yml +96 -0
  57. data/spec/cassettes/12/update_public_key.yml +70 -0
  58. data/spec/rundeck/client/execution_spec.rb +346 -0
  59. data/spec/rundeck/client/job_spec.rb +175 -0
  60. data/spec/rundeck/client/key_spec.rb +223 -0
  61. data/spec/spec_helper.rb +15 -60
  62. data/spec/support/helpers.rb +136 -0
  63. metadata +118 -35
  64. data/spec/fixtures/empty.xml +0 -0
  65. data/spec/fixtures/job.xml +0 -17
  66. data/spec/fixtures/job_executions.xml +0 -31
  67. data/spec/fixtures/job_run.xml +0 -16
  68. data/spec/fixtures/jobs_import.xml +0 -23
  69. data/spec/fixtures/jobs_my_project.xml +0 -14
  70. data/spec/fixtures/jobs_xml.xml +0 -32
  71. data/spec/fixtures/jobs_yaml.xml +0 -22
  72. data/spec/fixtures/key_contents_public.xml +0 -1
  73. data/spec/fixtures/key_private.xml +0 -8
  74. data/spec/fixtures/key_public.xml +0 -7
  75. data/spec/fixtures/keys.xml +0 -27
  76. data/spec/rundeck/client/jobs_spec.rb +0 -181
  77. data/spec/rundeck/client/keys_spec.rb +0 -216
@@ -0,0 +1,69 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: http://192.168.50.2:4440/api/12/jobs/import?format=xml
6
+ body:
7
+ encoding: UTF-8
8
+ string: |
9
+ xmlBatch=<joblist>
10
+ <job>
11
+ <loglevel>INFO</loglevel>
12
+ <sequence keepgoing='true' strategy='node-first'>
13
+ <command>
14
+ <exec>echo 'hello world'</exec>
15
+ </command>
16
+ </sequence>
17
+ <description>Check the status of anvils</description>
18
+ <name>My XML Job</name>
19
+ <context>
20
+ <project>anvils</project>
21
+ </context>
22
+ <group>anvils</group>
23
+ </job>
24
+ </joblist>
25
+ headers:
26
+ Content-Type:
27
+ - application/x-www-form-urlencoded
28
+ X-Rundeck-Auth-Token:
29
+ - i8iMfXUOpYzVJ9SAkh7pRQMTZI1Bnsyu
30
+ Accept:
31
+ - application/xml
32
+ response:
33
+ status:
34
+ code: 200
35
+ message: OK
36
+ headers:
37
+ Set-Cookie:
38
+ - JSESSIONID=ztal9jqk86ldot48wlmfki69;Path=/
39
+ Expires:
40
+ - Thu, 01 Jan 1970 00:00:00 GMT
41
+ X-Rundeck-Api-Xml-Response-Wrapper:
42
+ - 'true'
43
+ Content-Type:
44
+ - text/xml;charset=UTF-8
45
+ X-Rundeck-Api-Version:
46
+ - '12'
47
+ Transfer-Encoding:
48
+ - chunked
49
+ Server:
50
+ - Jetty(7.6.0.v20120127)
51
+ body:
52
+ encoding: UTF-8
53
+ string: |-
54
+ <result success='true' apiversion='12'>
55
+ <succeeded count='1'>
56
+ <job index='1' href='http://192.168.50.2:4440/api/12/job/cef53983-fdde-40c7-a969-784268a8b93c'>
57
+ <id>cef53983-fdde-40c7-a969-784268a8b93c</id>
58
+ <name>My XML Job</name>
59
+ <group>anvils</group>
60
+ <project>anvils</project>
61
+ <url>http://192.168.50.2:4440/job/show/cef53983-fdde-40c7-a969-784268a8b93c</url>
62
+ </job>
63
+ </succeeded>
64
+ <failed count='0' />
65
+ <skipped count='0' />
66
+ </result>
67
+ http_version:
68
+ recorded_at: Sat, 11 Oct 2014 14:41:53 GMT
69
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,63 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: http://192.168.50.2:4440/api/12/jobs/import?format=yaml
6
+ body:
7
+ encoding: UTF-8
8
+ string: |
9
+ xmlBatch=- project: anvils
10
+ loglevel: INFO
11
+ sequence:
12
+ keepgoing: true
13
+ strategy: node-first
14
+ commands:
15
+ - exec: echo 'hello world'
16
+ description: Check the status of anvils
17
+ name: My YAML Job
18
+ group: anvils
19
+ headers:
20
+ Content-Type:
21
+ - application/x-www-form-urlencoded
22
+ X-Rundeck-Auth-Token:
23
+ - i8iMfXUOpYzVJ9SAkh7pRQMTZI1Bnsyu
24
+ Accept:
25
+ - application/xml
26
+ response:
27
+ status:
28
+ code: 200
29
+ message: OK
30
+ headers:
31
+ Set-Cookie:
32
+ - JSESSIONID=jh34zvxx06xvo0rr14j9v7qr;Path=/
33
+ Expires:
34
+ - Thu, 01 Jan 1970 00:00:00 GMT
35
+ X-Rundeck-Api-Xml-Response-Wrapper:
36
+ - 'true'
37
+ Content-Type:
38
+ - text/xml;charset=UTF-8
39
+ X-Rundeck-Api-Version:
40
+ - '12'
41
+ Transfer-Encoding:
42
+ - chunked
43
+ Server:
44
+ - Jetty(7.6.0.v20120127)
45
+ body:
46
+ encoding: UTF-8
47
+ string: |-
48
+ <result success='true' apiversion='12'>
49
+ <succeeded count='1'>
50
+ <job index='1' href='http://192.168.50.2:4440/api/12/job/68c93b5c-a760-41bf-9a36-bb4184ea1cd1'>
51
+ <id>68c93b5c-a760-41bf-9a36-bb4184ea1cd1</id>
52
+ <name>My YAML Job</name>
53
+ <group>anvils</group>
54
+ <project>anvils</project>
55
+ <url>http://192.168.50.2:4440/job/show/68c93b5c-a760-41bf-9a36-bb4184ea1cd1</url>
56
+ </job>
57
+ </succeeded>
58
+ <failed count='0' />
59
+ <skipped count='0' />
60
+ </result>
61
+ http_version:
62
+ recorded_at: Sat, 11 Oct 2014 14:39:46 GMT
63
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,84 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://192.168.50.2:4440/api/12/job/2
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ X-Rundeck-Auth-Token:
11
+ - i8iMfXUOpYzVJ9SAkh7pRQMTZI1Bnsyu
12
+ Accept:
13
+ - application/xml
14
+ response:
15
+ status:
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ Set-Cookie:
20
+ - JSESSIONID=1x6qily26j1pm1cx93uonmvie9;Path=/
21
+ Expires:
22
+ - Thu, 01 Jan 1970 00:00:00 GMT
23
+ Content-Type:
24
+ - text/xml;charset=UTF-8
25
+ Transfer-Encoding:
26
+ - chunked
27
+ Server:
28
+ - Jetty(7.6.0.v20120127)
29
+ body:
30
+ encoding: UTF-8
31
+ string: |-
32
+ <joblist>
33
+ <job>
34
+ <id>48133ee7-c16f-4782-8217-5a0fdb755866</id>
35
+ <loglevel>INFO</loglevel>
36
+ <sequence keepgoing='false' strategy='node-first'>
37
+ <command>
38
+ <scriptargs>${option.repository} ${option.release} ${option.packages}</scriptargs>
39
+ <script><![CDATA[#!/bin/bash
40
+ set -eu
41
+ [[ $# != 3 ]] && {
42
+ echo >&2 'usage: $0 repository release pkg1,pkg2,pkgN'
43
+ exit 2
44
+ }
45
+ REPOSITORY=$1 RELEASE=$2 PACKAGELIST=$3
46
+
47
+ echo "# PROMOTE"
48
+ echo "## $REPOSITORY/$RELEASE"
49
+ echo "## Promote $REPOSITORY/$RELEASE..."
50
+
51
+ PACKAGES=( ${PACKAGELIST//,/ } )
52
+ echo "number packages: ${#PACKAGES[*]}"
53
+ echo
54
+ for package in ${PACKAGES[*]:-}
55
+ do
56
+ echo "- $REPOSITORY/$RELEASE/$package"
57
+ done
58
+
59
+ exit $?]]></script>
60
+ </command>
61
+ </sequence>
62
+ <description>promote the packages to the ops repository.</description>
63
+ <name>Promote</name>
64
+ <context>
65
+ <project>anvils</project>
66
+ <options>
67
+ <option name='packages' valuesUrl='http://localhost/anvils/options/packages/${option.release.value}.json' enforcedvalues='true' required='true' multivalued='true' delimiter=','>
68
+ <description>packages versions</description>
69
+ </option>
70
+ <option name='release' valuesUrl='http://localhost/anvils/options/releases/${option.repository.value}.json' enforcedvalues='true' required='true'>
71
+ <description>release tag</description>
72
+ </option>
73
+ <option name='repository' valuesUrl='http://localhost/anvils/options/repositories.json' enforcedvalues='true' required='true'>
74
+ <description>repository name</description>
75
+ </option>
76
+ </options>
77
+ </context>
78
+ <uuid>48133ee7-c16f-4782-8217-5a0fdb755866</uuid>
79
+ <group>anvils</group>
80
+ </job>
81
+ </joblist>
82
+ http_version:
83
+ recorded_at: Sat, 11 Oct 2014 13:25:26 GMT
84
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,96 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://192.168.50.2:4440/api/12/job/1/executions
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ X-Rundeck-Auth-Token:
11
+ - i8iMfXUOpYzVJ9SAkh7pRQMTZI1Bnsyu
12
+ Accept:
13
+ - application/xml
14
+ response:
15
+ status:
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ Set-Cookie:
20
+ - JSESSIONID=ekctkun9qhup1v2fid408gnyl;Path=/
21
+ Expires:
22
+ - Thu, 01 Jan 1970 00:00:00 GMT
23
+ Content-Type:
24
+ - text/xml;charset=UTF-8
25
+ X-Rundeck-Api-Version:
26
+ - '12'
27
+ Transfer-Encoding:
28
+ - chunked
29
+ Server:
30
+ - Jetty(7.6.0.v20120127)
31
+ body:
32
+ encoding: UTF-8
33
+ string: |-
34
+ <result success='true' apiversion='12'>
35
+ <executions count='2'>
36
+ <execution id='2' href='http://192.168.50.2:4440/execution/follow/2' status='succeeded' project='anvils'>
37
+ <user>admin</user>
38
+ <date-started unixtime='1413035146499'>2014-10-11T13:45:46Z</date-started>
39
+ <date-ended unixtime='1413035149280'>2014-10-11T13:45:49Z</date-ended>
40
+ <job id='308f438c-3950-4b62-9e49-97182edab157' averageDuration='4065'>
41
+ <name>nightly_catalog_rebuild</name>
42
+ <group>anvils</group>
43
+ <project>anvils</project>
44
+ <description>rebuild the catalog data</description>
45
+ <options>
46
+ <option name='catalog' value='inventory' />
47
+ </options>
48
+ </job>
49
+ <description>#!/bin/bash
50
+ set -eu
51
+ CATALOG=$1
52
+ echo "# Rebuild catalog: $CATALOG"
53
+ echo ""
54
+ echo "- customer: ${RD_NODE_ANVILS_CUSTOMER}"
55
+ echo "- location: ${RD_NODE_ANVILS_LOCATION}"
56
+ echo "- database: ${RD_NODE_NAME:-}"
57
+ echo "Completed."
58
+ exit $? -- ${option.catalog}</description>
59
+ <argstring>-catalog inventory</argstring>
60
+ <successfulNodes>
61
+ <node name='db1.anvils.com' />
62
+ </successfulNodes>
63
+ </execution>
64
+ <execution id='1' href='http://192.168.50.2:4440/execution/follow/1' status='succeeded' project='anvils'>
65
+ <user>admin</user>
66
+ <date-started unixtime='1413035126917'>2014-10-11T13:45:26Z</date-started>
67
+ <date-ended unixtime='1413035132266'>2014-10-11T13:45:32Z</date-ended>
68
+ <job id='308f438c-3950-4b62-9e49-97182edab157' averageDuration='4065'>
69
+ <name>nightly_catalog_rebuild</name>
70
+ <group>anvils</group>
71
+ <project>anvils</project>
72
+ <description>rebuild the catalog data</description>
73
+ <options>
74
+ <option name='catalog' value='inventory' />
75
+ </options>
76
+ </job>
77
+ <description>#!/bin/bash
78
+ set -eu
79
+ CATALOG=$1
80
+ echo "# Rebuild catalog: $CATALOG"
81
+ echo ""
82
+ echo "- customer: ${RD_NODE_ANVILS_CUSTOMER}"
83
+ echo "- location: ${RD_NODE_ANVILS_LOCATION}"
84
+ echo "- database: ${RD_NODE_NAME:-}"
85
+ echo "Completed."
86
+ exit $? -- ${option.catalog}</description>
87
+ <argstring>-catalog inventory</argstring>
88
+ <successfulNodes>
89
+ <node name='db1.anvils.com' />
90
+ </successfulNodes>
91
+ </execution>
92
+ </executions>
93
+ </result>
94
+ http_version:
95
+ recorded_at: Sat, 11 Oct 2014 13:46:05 GMT
96
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,76 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://192.168.50.2:4440/api/12/project/anvils/jobs
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ X-Rundeck-Auth-Token:
11
+ - i8iMfXUOpYzVJ9SAkh7pRQMTZI1Bnsyu
12
+ Accept:
13
+ - application/xml
14
+ response:
15
+ status:
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ Set-Cookie:
20
+ - JSESSIONID=161bjed4yj1ab1bq2kyofi20ne;Path=/
21
+ Expires:
22
+ - Thu, 01 Jan 1970 00:00:00 GMT
23
+ X-Rundeck-Api-Xml-Response-Wrapper:
24
+ - 'false'
25
+ Content-Type:
26
+ - application/xml;charset=UTF-8
27
+ X-Rundeck-Api-Version:
28
+ - '12'
29
+ Transfer-Encoding:
30
+ - chunked
31
+ Server:
32
+ - Jetty(7.6.0.v20120127)
33
+ body:
34
+ encoding: UTF-8
35
+ string: |-
36
+ <jobs count='6'>
37
+ <job id='48133ee7-c16f-4782-8217-5a0fdb755866'>
38
+ <name>Promote</name>
39
+ <group>anvils</group>
40
+ <project>anvils</project>
41
+ <description>promote the packages to the ops repository.</description>
42
+ </job>
43
+ <job id='576e8baa-55ac-43ad-b777-f5e6f84fc4fd'>
44
+ <name>Restart</name>
45
+ <group>anvils/web</group>
46
+ <project>anvils</project>
47
+ <description>restart the web servers</description>
48
+ </job>
49
+ <job id='2065685b-776a-4f1a-8fa8-7df90f9060aa'>
50
+ <name>Status</name>
51
+ <group>anvils</group>
52
+ <project>anvils</project>
53
+ <description>Check the status of anvils</description>
54
+ </job>
55
+ <job id='308f438c-3950-4b62-9e49-97182edab157'>
56
+ <name>nightly_catalog_rebuild</name>
57
+ <group>anvils</group>
58
+ <project>anvils</project>
59
+ <description>rebuild the catalog data</description>
60
+ </job>
61
+ <job id='6a4d6655-4a5b-4e40-90ce-9feb03e0b387'>
62
+ <name>start</name>
63
+ <group>anvils/web</group>
64
+ <project>anvils</project>
65
+ <description>start the web servers</description>
66
+ </job>
67
+ <job id='33e43e6b-c83d-42a9-b399-76b93bd728c1'>
68
+ <name>stop</name>
69
+ <group>anvils/web</group>
70
+ <project>anvils</project>
71
+ <description>stop the web servers</description>
72
+ </job>
73
+ </jobs>
74
+ http_version:
75
+ recorded_at: Sat, 11 Oct 2014 13:25:26 GMT
76
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,67 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://192.168.50.2:4440/api/12/storage/keys/path/to/key
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ X-Rundeck-Auth-Token:
11
+ - i8iMfXUOpYzVJ9SAkh7pRQMTZI1Bnsyu
12
+ Accept:
13
+ - application/xml
14
+ response:
15
+ status:
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ Set-Cookie:
20
+ - JSESSIONID=1hgww22v3ttgu184690t16xhqt;Path=/
21
+ Expires:
22
+ - Thu, 01 Jan 1970 00:00:00 GMT
23
+ Content-Type:
24
+ - application/xml;charset=utf-8
25
+ Transfer-Encoding:
26
+ - chunked
27
+ Server:
28
+ - Jetty(7.6.0.v20120127)
29
+ body:
30
+ encoding: UTF-8
31
+ string: <resource path='keys/path/to/key' type='file' url='http://192.168.50.2:4440/api/12/storage/keys/path/to/key'
32
+ name='key'><resource-meta><Rundeck-content-type>application/pgp-key</Rundeck-content-type><Rundeck-content-size>395</Rundeck-content-size></resource-meta></resource>
33
+ http_version:
34
+ recorded_at: Sat, 11 Oct 2014 19:01:24 GMT
35
+ - request:
36
+ method: get
37
+ uri: http://192.168.50.2:4440/api/12/storage/keys/path/to/key
38
+ body:
39
+ encoding: US-ASCII
40
+ string: ''
41
+ headers:
42
+ Accept:
43
+ - application/pgp-keys
44
+ X-Rundeck-Auth-Token:
45
+ - i8iMfXUOpYzVJ9SAkh7pRQMTZI1Bnsyu
46
+ response:
47
+ status:
48
+ code: 200
49
+ message: OK
50
+ headers:
51
+ Set-Cookie:
52
+ - JSESSIONID=1iv0mz66r69do13f2jcu651s5b;Path=/
53
+ Expires:
54
+ - Thu, 01 Jan 1970 00:00:00 GMT
55
+ Content-Type:
56
+ - application/pgp-key
57
+ Content-Length:
58
+ - '395'
59
+ Server:
60
+ - Jetty(7.6.0.v20120127)
61
+ body:
62
+ encoding: UTF-8
63
+ string: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC3oblgkLjHhSJFAHTx2wtq8Mz3YdWdAg2zh+IBSBmw8gJMCFsCCftdFdT4/x9fVpF5GLangsdIi12XmGNPZaQ0IfU2LD1+mW2I2GeU6WumgG395Yx13asm0LTSNDikO/7V53D2lz5F7t8NBgPgdKaGb97GlAsCC74tIUJ0vsWPTk4A3sPRHHAV9DfCtl7moa3i2vmhuMDbBfAYScykWoUYYj366pIqe7DVpSBV/uJG95zV8lP+GYVJqy2jMScEmYEH+ZCgW+M6rP6hKJeZeLC+gd/D0HwB1vEqmaLj4B9JOYmphPWPgU87okl/vxDHRSHt5ZBwLu7GEtrlekevoL+p
64
+ test@localhost
65
+ http_version:
66
+ recorded_at: Sat, 11 Oct 2014 19:01:24 GMT
67
+ recorded_with: VCR 2.9.3