berkshelf 1.1.6 → 1.2.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. data/.cane +4 -0
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +25 -0
  4. data/CONTRIBUTING.md +9 -0
  5. data/Gemfile +1 -7
  6. data/Guardfile +4 -2
  7. data/LICENSE +4 -4
  8. data/README.md +34 -11
  9. data/Thorfile +12 -11
  10. data/berkshelf-complete.sh +68 -0
  11. data/berkshelf.gemspec +23 -10
  12. data/bin/berks +2 -0
  13. data/features/config.feature +5 -4
  14. data/features/configure_command.feature +1 -0
  15. data/features/install_command.feature +7 -43
  16. data/features/step_definitions/configure_cli_steps.rb +6 -0
  17. data/features/step_definitions/filesystem_steps.rb +3 -1
  18. data/features/step_definitions/json_steps.rb +7 -0
  19. data/features/support/env.rb +3 -8
  20. data/features/upload_command.feature +49 -101
  21. data/generator_files/Vagrantfile.erb +1 -1
  22. data/generator_files/gitignore.erb +6 -1
  23. data/lib/berkshelf.rb +17 -26
  24. data/lib/berkshelf/base_generator.rb +8 -7
  25. data/lib/berkshelf/berksfile.rb +33 -13
  26. data/lib/berkshelf/cached_cookbook.rb +16 -37
  27. data/lib/berkshelf/chef.rb +11 -0
  28. data/lib/berkshelf/chef/config.rb +93 -0
  29. data/lib/berkshelf/chef/cookbook.rb +8 -0
  30. data/lib/berkshelf/chef/cookbook/chefignore.rb +60 -0
  31. data/lib/berkshelf/chef/cookbook/metadata.rb +556 -0
  32. data/lib/berkshelf/chef/cookbook/syntax_check.rb +158 -0
  33. data/lib/berkshelf/chef/digester.rb +67 -0
  34. data/lib/berkshelf/cli.rb +18 -4
  35. data/lib/berkshelf/command.rb +117 -0
  36. data/lib/berkshelf/community_rest.rb +135 -0
  37. data/lib/berkshelf/config.rb +16 -50
  38. data/lib/berkshelf/cookbook_generator.rb +5 -9
  39. data/lib/berkshelf/cookbook_source.rb +1 -1
  40. data/lib/berkshelf/cookbook_store.rb +5 -1
  41. data/lib/berkshelf/downloader.rb +4 -4
  42. data/lib/berkshelf/errors.rb +6 -0
  43. data/lib/berkshelf/formatters.rb +3 -3
  44. data/lib/berkshelf/formatters/human_readable.rb +1 -1
  45. data/lib/berkshelf/formatters/json.rb +1 -1
  46. data/lib/berkshelf/git.rb +2 -2
  47. data/lib/berkshelf/init_generator.rb +5 -11
  48. data/lib/berkshelf/location.rb +7 -6
  49. data/lib/berkshelf/locations/chef_api_location.rb +54 -108
  50. data/lib/berkshelf/locations/git_location.rb +1 -1
  51. data/lib/berkshelf/locations/github_location.rb +1 -1
  52. data/lib/berkshelf/locations/path_location.rb +22 -3
  53. data/lib/berkshelf/locations/site_location.rb +31 -99
  54. data/lib/berkshelf/mixin.rb +10 -0
  55. data/lib/berkshelf/mixin/checksum.rb +16 -0
  56. data/lib/berkshelf/mixin/params_validate.rb +218 -0
  57. data/lib/berkshelf/mixin/path_helpers.rb +30 -0
  58. data/lib/berkshelf/mixin/shell_out.rb +23 -0
  59. data/lib/berkshelf/resolver.rb +5 -3
  60. data/lib/berkshelf/ui.rb +5 -1
  61. data/lib/berkshelf/uploader.rb +11 -5
  62. data/lib/berkshelf/vagrant.rb +1 -1
  63. data/lib/berkshelf/vagrant/action/clean.rb +1 -1
  64. data/lib/berkshelf/vagrant/action/install.rb +1 -1
  65. data/lib/berkshelf/vagrant/action/set_ui.rb +2 -2
  66. data/lib/berkshelf/vagrant/action/upload.rb +1 -1
  67. data/lib/berkshelf/vagrant/action/validate.rb +1 -1
  68. data/lib/berkshelf/vagrant/config.rb +1 -1
  69. data/lib/berkshelf/vagrant/middleware.rb +1 -1
  70. data/lib/berkshelf/version.rb +1 -1
  71. data/lib/thor/monkies/shell.rb +8 -0
  72. data/spec/fixtures/cookbooks/example_cookbook-0.5.0/metadata.rb +1 -1
  73. data/spec/fixtures/cookbooks/example_cookbook/metadata.rb +1 -1
  74. data/spec/fixtures/cookbooks/nginx-0.100.5/templates/default/plugins/nginx.rb.erb +1 -1
  75. data/spec/spec_helper.rb +81 -21
  76. data/spec/support/chef_api.rb +29 -28
  77. data/spec/support/knife.rb +2 -2
  78. data/spec/support/test_generators.rb +27 -0
  79. data/spec/unit/berkshelf/berksfile_spec.rb +2 -2
  80. data/spec/unit/berkshelf/cached_cookbook_spec.rb +10 -2
  81. data/spec/unit/berkshelf/community_rest_spec.rb +120 -0
  82. data/spec/unit/berkshelf/config_spec.rb +0 -12
  83. data/spec/unit/berkshelf/cookbook_generator_spec.rb +65 -67
  84. data/spec/unit/berkshelf/cookbook_source_spec.rb +1 -1
  85. data/spec/unit/berkshelf/git_spec.rb +17 -12
  86. data/spec/unit/berkshelf/init_generator_spec.rb +126 -120
  87. data/spec/unit/berkshelf/location_spec.rb +2 -2
  88. data/spec/unit/berkshelf/locations/chef_api_location_spec.rb +90 -186
  89. data/spec/unit/berkshelf/locations/git_location_spec.rb +87 -82
  90. data/spec/unit/berkshelf/locations/path_location_spec.rb +34 -35
  91. data/spec/unit/berkshelf/locations/site_location_spec.rb +12 -115
  92. data/spec/unit/berkshelf/resolver_spec.rb +96 -87
  93. data/spec/unit/berkshelf/ui_spec.rb +132 -0
  94. data/spec/unit/berkshelf/uploader_spec.rb +18 -12
  95. data/spec/unit/chef/config_spec.rb +9 -0
  96. data/spec/unit/chef/cookbook/metadata_spec.rb +5 -0
  97. data/spec/unit/chef/digester_spec.rb +41 -0
  98. metadata +263 -28
@@ -0,0 +1,30 @@
1
+ module Berkshelf::Mixin
2
+ # @author Jamie Winsor <reset@riotgames.com>
3
+ module PathHelpers
4
+ # Converts a path to a path usable for your current platform
5
+ #
6
+ # @param [String] path
7
+ #
8
+ # @return [String]
9
+ def platform_specific_path(path)
10
+ if RUBY_PLATFORM =~ /mswin|mingw|windows/
11
+ system_drive = ENV['SYSTEMDRIVE'] ? ENV['SYSTEMDRIVE'] : ""
12
+ path = win_slashify File.join(system_drive, path.split('/')[2..-1])
13
+ end
14
+
15
+ path
16
+ end
17
+
18
+ # Convert a unixy filepath to a windowsy filepath. Swaps forward slashes for
19
+ # double backslashes
20
+ #
21
+ # @param [String] path
22
+ # filepath to convert
23
+ #
24
+ # @return [String]
25
+ # converted filepath
26
+ def win_slashify(path)
27
+ path.gsub(File::SEPARATOR, (File::ALT_SEPARATOR || '\\'))
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,23 @@
1
+ require 'mixlib/shellout'
2
+
3
+ module Berkshelf::Mixin
4
+ # @author Jamie Winsor <reset@riotgames.com>
5
+ module ShellOut
6
+ # @return [Mixlib::ShellOut]
7
+ def shell_out(*command_args)
8
+ cmd = Mixlib::ShellOut.new(*command_args)
9
+ if STDOUT.tty?
10
+ cmd.live_stream = STDOUT
11
+ end
12
+ cmd.run_command
13
+ cmd
14
+ end
15
+
16
+ # @return [Mixlib::ShellOut]
17
+ def shell_out!(*command_args)
18
+ cmd = shell_out(*command_args)
19
+ cmd.error!
20
+ cmd
21
+ end
22
+ end
23
+ end
@@ -1,5 +1,5 @@
1
1
  module Berkshelf
2
- # @author Jamie Winsor <jamie@vialstudios.com>
2
+ # @author Jamie Winsor <reset@riotgames.com>
3
3
  class Resolver
4
4
  extend Forwardable
5
5
 
@@ -22,8 +22,10 @@ module Berkshelf
22
22
  add_source(source, false)
23
23
  end
24
24
 
25
- Array(options[:sources]).each do |source|
26
- add_source_dependencies(source)
25
+ unless options[:skip_dependencies]
26
+ Array(options[:sources]).each do |source|
27
+ add_source_dependencies(source)
28
+ end
27
29
  end
28
30
  end
29
31
 
@@ -1,5 +1,5 @@
1
1
  module Berkshelf
2
- class UI < ::Thor::Shell::Basic
2
+ module UI
3
3
  # Mute the output of this instance of UI until {#unmute!} is called
4
4
  def mute!
5
5
  @mute = true
@@ -29,6 +29,10 @@ module Berkshelf
29
29
  say(message, color)
30
30
  end
31
31
 
32
+ def deprecated(message)
33
+ warn("[DEPRECATION] #{message}")
34
+ end
35
+
32
36
  def error(message, color = :red)
33
37
  return if quiet?
34
38
 
@@ -1,6 +1,12 @@
1
1
  module Berkshelf
2
- # @author Jamie Winsor <jamie@vialstudios.com>
2
+ # @author Jamie Winsor <reset@riotgames.com>
3
3
  class Uploader
4
+ class << self
5
+ def finalize
6
+ conn.terminate if conn.alive?
7
+ end
8
+ end
9
+
4
10
  extend Forwardable
5
11
 
6
12
  def_delegator :conn, :client_name
@@ -28,7 +34,9 @@ module Berkshelf
28
34
  # @option options [URI, String, Hash] :proxy
29
35
  # URI, String, or Hash of HTTP proxy options
30
36
  def initialize(options = {})
31
- @conn = Ridley.connection(options)
37
+ @conn = Ridley.new(options)
38
+
39
+ ObjectSpace.define_finalizer(self, self.class.method(:finalize).to_proc)
32
40
  end
33
41
 
34
42
  # Uploads a CachedCookbook from a CookbookStore to this instances Chef Server URL
@@ -51,13 +59,11 @@ module Berkshelf
51
59
  # @return [Boolean]
52
60
  def upload(cookbook, options = {})
53
61
  cookbook.validate! unless options[:skip_syntax_check]
54
- mutex = Mutex.new
55
62
  checksums = cookbook.checksums.dup
56
63
  sandbox = conn.sandbox.create(checksums.keys)
57
64
 
58
- sandbox.multi_upload(checksums)
65
+ sandbox.upload(checksums)
59
66
  sandbox.commit
60
- sandbox.terminate
61
67
 
62
68
  conn.cookbook.save(
63
69
  cookbook.cookbook_name,
@@ -3,7 +3,7 @@ require 'berkshelf'
3
3
  require 'berkshelf/vagrant/errors'
4
4
 
5
5
  module Berkshelf
6
- # @author Jamie Winsor <jamie@vialstudios.com>
6
+ # @author Jamie Winsor <reset@riotgames.com>
7
7
  # @author Andrew Garson <andrew.garson@gmail.com>
8
8
  module Vagrant
9
9
  module Action
@@ -1,7 +1,7 @@
1
1
  module Berkshelf
2
2
  module Vagrant
3
3
  module Action
4
- # @author Jamie Winsor <jamie@vialstudios.com>
4
+ # @author Jamie Winsor <reset@riotgames.com>
5
5
  class Clean
6
6
  attr_reader :shelf
7
7
 
@@ -1,7 +1,7 @@
1
1
  module Berkshelf
2
2
  module Vagrant
3
3
  module Action
4
- # @author Jamie Winsor <jamie@vialstudios.com>
4
+ # @author Jamie Winsor <reset@riotgames.com>
5
5
  # @author Andrew Garson <andrew.garson@gmail.com>
6
6
  class Install
7
7
  attr_reader :shelf
@@ -1,14 +1,14 @@
1
1
  module Berkshelf
2
2
  module Vagrant
3
3
  module Action
4
- # @author Jamie Winsor <jamie@vialstudios.com>
4
+ # @author Jamie Winsor <reset@riotgames.com>
5
5
  class SetUI
6
6
  def initialize(app, env)
7
7
  @app = app
8
8
  end
9
9
 
10
10
  def call(env)
11
- Berkshelf.ui = ::Vagrant::UI::Colored.new("Berkshelf")
11
+ Berkshelf.ui = ::Vagrant::UI::Colored.new('Berkshelf')
12
12
  @app.call(env)
13
13
  end
14
14
  end
@@ -1,7 +1,7 @@
1
1
  module Berkshelf
2
2
  module Vagrant
3
3
  module Action
4
- # @author Jamie Winsor <jamie@vialstudios.com>
4
+ # @author Jamie Winsor <reset@riotgames.com>
5
5
  class Upload
6
6
  attr_reader :berksfile
7
7
 
@@ -1,7 +1,7 @@
1
1
  module Berkshelf
2
2
  module Vagrant
3
3
  module Action
4
- # @author Jamie Winsor <jamie@vialstudios.com>
4
+ # @author Jamie Winsor <reset@riotgames.com>
5
5
  #
6
6
  # As of Vagrant 1.0.5 it is not possible to validate configuration values of
7
7
  # a configuraiton that was not explicitly described in a Vagrant::Config.run block.
@@ -1,6 +1,6 @@
1
1
  module Berkshelf
2
2
  module Vagrant
3
- # @author Jamie Winsor <jamie@vialstudios.com>
3
+ # @author Jamie Winsor <reset@riotgames.com>
4
4
  # @author Andrew Garson <andrew.garson@gmail.com>
5
5
  class Config < ::Vagrant::Config::Base
6
6
  # @return [String]
@@ -1,6 +1,6 @@
1
1
  module Berkshelf
2
2
  module Vagrant
3
- # @author Jamie Winsor <jamie@vialstudios.com>
3
+ # @author Jamie Winsor <reset@riotgames.com>
4
4
  #
5
5
  # Middleware stacks for use with Vagrant
6
6
  module Middleware
@@ -1,3 +1,3 @@
1
1
  module Berkshelf
2
- VERSION = "1.1.6"
2
+ VERSION = "1.2.0.rc1"
3
3
  end
@@ -0,0 +1,8 @@
1
+ require 'berkshelf/ui'
2
+
3
+ # @author Seth Vargo <sethvargo@gmail.com>
4
+ class ::Thor::Shell::Color
5
+ # Include the Berkshelf UI methods - this is used by both
6
+ # Vagrant and Berkshelf UI
7
+ include ::Berkshelf::UI
8
+ end
@@ -1,6 +1,6 @@
1
1
  name "example_cookbook"
2
2
  maintainer "Josiah Kiehl"
3
- maintainer_email "josiah@skirmisher.net"
3
+ maintainer_email "jkiehl@riotgames.com"
4
4
  license "DO WHAT YOU WANT CAUSE A PIRATE IS FREE"
5
5
  description "Installs/Configures example_cookbook"
6
6
  long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
@@ -1,5 +1,5 @@
1
1
  maintainer "Josiah Kiehl"
2
- maintainer_email "josiah@skirmisher.net"
2
+ maintainer_email "jkiehl@riotgames.com"
3
3
  license "DO WHAT YOU WANT CAUSE A PIRATE IS FREE"
4
4
  description "Installs/Configures example_cookbook"
5
5
  long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
@@ -1,5 +1,5 @@
1
1
  #
2
- # Author:: Jamie Winsor (<jamie@vialstudios.com>)
2
+ # Author:: Jamie Winsor (<reset@riotgames.com>)
3
3
  #
4
4
  # Copyright 2012, Riot Games
5
5
  #
@@ -1,8 +1,6 @@
1
1
  require 'rubygems'
2
-
3
2
  require 'bundler'
4
3
  require 'spork'
5
- require 'vcr'
6
4
 
7
5
  Spork.prefork do
8
6
  require 'json_spec'
@@ -16,11 +14,6 @@ Spork.prefork do
16
14
 
17
15
  Dir[File.join(APP_ROOT, "spec/support/**/*.rb")].each {|f| require f}
18
16
 
19
- VCR.configure do |c|
20
- c.cassette_library_dir = File.join(File.dirname(__FILE__), 'fixtures', 'vcr_cassettes')
21
- c.hook_into :webmock
22
- end
23
-
24
17
  RSpec.configure do |config|
25
18
  config.include Berkshelf::RSpec::FileSystemMatchers
26
19
  config.include JsonSpec::Helpers
@@ -31,20 +24,6 @@ Spork.prefork do
31
24
  config.filter_run focus: true
32
25
  config.run_all_when_everything_filtered = true
33
26
 
34
- config.around do |example|
35
- # Dynamically create cassettes based on the name of the example
36
- # being run. This creates a new cassette for every test.
37
- cur = example.metadata
38
- identifiers = [example.metadata[:description_args]]
39
- while cur = cur[:example_group] do
40
- identifiers << cur[:description_args]
41
- end
42
-
43
- VCR.use_cassette(identifiers.reverse.join(' ')) do
44
- example.run
45
- end
46
- end
47
-
48
27
  config.before(:each) do
49
28
  clean_tmp_path
50
29
  Berkshelf.cookbook_store = Berkshelf::CookbookStore.new(tmp_path.join("downloader_tmp"))
@@ -90,10 +69,91 @@ Spork.prefork do
90
69
  FileUtils.mkdir_p(tmp_path)
91
70
  end
92
71
 
72
+ def git_origin_for(repo, options = {})
73
+ "file://#{generate_fake_git_remote("git@github.com/RiotGames/#{repo}.git", options)}/.git"
74
+ end
75
+
76
+ def generate_fake_git_remote(uri, options = {})
77
+ remote_bucket = Pathname.new(File.dirname(__FILE__)).join('tmp', 'remote_repos')
78
+ FileUtils.mkdir_p(remote_bucket)
79
+
80
+ repo_name = uri.to_s.split('/').last.split('.')
81
+ name = if repo_name.last == 'git'
82
+ repo_name.first
83
+ else
84
+ repo_name.last
85
+ end
86
+ name = 'rspec_cookbook' if name.nil? or name.empty?
87
+
88
+ path = ''
89
+ capture(:stdout) do
90
+ Dir.chdir(remote_bucket) do
91
+ Berkshelf::Cli.new.invoke(:cookbook, [name], skip_vagrant: true, force: true)
92
+ end
93
+
94
+ Dir.chdir(path = remote_bucket.join(name)) do
95
+ run! "git config receive.denyCurrentBranch ignore"
96
+ run! "echo '# a change!' >> content_file"
97
+ run! "git add ."
98
+ run "git commit -am 'A commit.'"
99
+ options[:tags].each do |tag|
100
+ run! "echo '#{tag}' > content_file"
101
+ run! "git add content_file"
102
+ run "git commit -am '#{tag} content'"
103
+ run "git tag '#{tag}' 2> /dev/null"
104
+ end if options.has_key? :tags
105
+ end
106
+ end
107
+ path
108
+ end
109
+
110
+ def git_sha_for_tag(repo, tag)
111
+ Dir.chdir local_git_origin_path_for(repo) do
112
+ run!("git show-ref '#{tag}'").chomp.split(/\s/).first
113
+ end
114
+ end
115
+
116
+ def local_git_origin_path_for(repo)
117
+ remote_repos_path = tmp_path.join('remote_repos')
118
+ FileUtils.mkdir_p(remote_repos_path)
119
+ remote_repos_path.join(repo)
120
+ end
121
+
122
+ def clone_target
123
+ tmp_path.join('clone_targets')
124
+ end
125
+
126
+ def clone_target_for(repo)
127
+ clone_target.join(repo)
128
+ end
129
+
130
+ def run!(cmd)
131
+ out = `#{cmd}`
132
+ raise "#{cmd} did not succeed:\n\tstatus: #{$?.exitstatus}\n\toutput: #{out}" unless $?.success?
133
+ out
134
+ end
135
+
136
+ def run(cmd)
137
+ `#{cmd}`
138
+ end
139
+
93
140
  Berkshelf::RSpec::Knife.load_knife_config(File.join(APP_ROOT, 'spec/knife.rb'))
94
141
  end
95
142
 
96
143
  Spork.each_run do
97
144
  require 'berkshelf'
98
145
  require 'berkshelf/vagrant'
146
+
147
+ module Berkshelf
148
+ class GitLocation
149
+ alias :real_clone :clone
150
+ def clone
151
+ fake_remote = generate_fake_git_remote(uri, tags: @branch ? [@branch] : [])
152
+ tmp_clone = File.join(self.class.tmpdir, uri.gsub(/[\/:]/,'-'))
153
+ @uri = "file://#{fake_remote}"
154
+ real_clone
155
+ end
156
+ end
157
+ end
99
158
  end
159
+
@@ -1,7 +1,3 @@
1
- require 'pathname'
2
- require 'chef/rest'
3
- require 'chef/cookbook_version'
4
-
5
1
  module Berkshelf
6
2
  module RSpec
7
3
  module ChefAPI
@@ -9,7 +5,7 @@ module Berkshelf
9
5
  #
10
6
  # @return [Array]
11
7
  def get_cookbooks
12
- rest.get_rest("cookbooks")
8
+ ridley.cookbook.all
13
9
  end
14
10
 
15
11
  def upload_cookbook(path)
@@ -17,31 +13,30 @@ module Berkshelf
17
13
  uploader.upload(cached)
18
14
  end
19
15
 
20
- # Remove all versions of all cookbooks from the Chef Server defined in your
21
- # Knife config.
22
- def purge_cookbooks
23
- get_cookbooks.each do |name, info|
24
- info["versions"].each do |version_info|
25
- rest.delete_rest("cookbooks/#{name}/#{version_info["version"]}?purge=true")
26
- end
27
- end
28
- end
29
-
30
16
  # Remove the version of the given cookbook from the Chef Server defined
31
17
  # in your Knife config.
32
18
  #
33
19
  # @param [#to_s] name
34
20
  # @param [#to_s] version
35
- def purge_cookbook(name, version)
36
- rest.delete_rest("cookbooks/#{name}/#{version}?purge=true")
37
- rescue Net::HTTPServerException => e
38
- raise unless e.to_s =~ /^404/
21
+ def purge_cookbook(name, version = nil)
22
+ if version.nil?
23
+ ridley.cookbook.delete_all(name, purge: true)
24
+ else
25
+ ridley.cookbook.delete(name, version, purge: true)
26
+ end
27
+ rescue Ridley::Errors::HTTPNotFound
28
+ true
39
29
  end
40
30
 
41
- def server_has_cookbook?(name, version)
42
- rest.get_rest("cookbooks/#{name}/#{version}")
43
- true
44
- rescue Net::HTTPServerException => e
31
+ def server_has_cookbook?(name, version = nil)
32
+ versions = ridley.cookbook.versions(name)
33
+
34
+ if version.nil?
35
+ !versions.empty?
36
+ else
37
+ !versions.find { |ver| ver == version }.nil?
38
+ end
39
+ rescue Ridley::Errors::HTTPNotFound
45
40
  false
46
41
  end
47
42
 
@@ -98,15 +93,21 @@ EOF
98
93
 
99
94
  private
100
95
 
101
- def rest
102
- quietly { Chef::REST.new(Chef::Config[:chef_server_url]) }
96
+ def ridley
97
+ @ridley ||= Ridley.new(
98
+ server_url: Berkshelf::Chef::Config[:chef_server_url],
99
+ client_name: Berkshelf::Chef::Config[:node_name],
100
+ client_key: Berkshelf::Chef::Config[:client_key],
101
+ ssl: { verify: false }
102
+ )
103
103
  end
104
104
 
105
105
  def uploader
106
106
  @uploader ||= Berkshelf::Uploader.new(
107
- server_url: Chef::Config[:chef_server_url],
108
- client_name: Chef::Config[:node_name],
109
- client_key: Chef::Config[:client_key]
107
+ server_url: Berkshelf::Chef::Config[:chef_server_url],
108
+ client_name: Berkshelf::Chef::Config[:node_name],
109
+ client_key: Berkshelf::Chef::Config[:client_key],
110
+ ssl: { verify: false }
110
111
  )
111
112
  end
112
113
  end