vagrant-command-dns 0.1.0

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 (35) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/CODE_OF_CONDUCT.md +13 -0
  4. data/Gemfile +9 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +25 -0
  7. data/Rakefile +14 -0
  8. data/bin/console +14 -0
  9. data/bin/setup +7 -0
  10. data/lib/vagrant-command-dns/action/get_ip.rb +78 -0
  11. data/lib/vagrant-command-dns/action/host/create.rb +49 -0
  12. data/lib/vagrant-command-dns/action/host/destroy.rb +49 -0
  13. data/lib/vagrant-command-dns/action/host.rb +31 -0
  14. data/lib/vagrant-command-dns/action/route53/connect.rb +42 -0
  15. data/lib/vagrant-command-dns/action/route53/create.rb +71 -0
  16. data/lib/vagrant-command-dns/action/route53/destroy.rb +69 -0
  17. data/lib/vagrant-command-dns/action/route53.rb +34 -0
  18. data/lib/vagrant-command-dns/action/show_ip.rb +23 -0
  19. data/lib/vagrant-command-dns/action.rb +26 -0
  20. data/lib/vagrant-command-dns/command/host/create.rb +34 -0
  21. data/lib/vagrant-command-dns/command/host/destroy.rb +46 -0
  22. data/lib/vagrant-command-dns/command/host/root.rb +74 -0
  23. data/lib/vagrant-command-dns/command/ip.rb +34 -0
  24. data/lib/vagrant-command-dns/command/root.rb +77 -0
  25. data/lib/vagrant-command-dns/command/route53/create.rb +34 -0
  26. data/lib/vagrant-command-dns/command/route53/destroy.rb +46 -0
  27. data/lib/vagrant-command-dns/command/route53/root.rb +74 -0
  28. data/lib/vagrant-command-dns/config.rb +90 -0
  29. data/lib/vagrant-command-dns/errors.rb +31 -0
  30. data/lib/vagrant-command-dns/plugin.rb +69 -0
  31. data/lib/vagrant-command-dns/version.rb +5 -0
  32. data/lib/vagrant-command-dns.rb +20 -0
  33. data/locales/en.yml +43 -0
  34. data/vagrant-command-dns.gemspec +25 -0
  35. metadata +119 -0
@@ -0,0 +1,46 @@
1
+ require 'optparse'
2
+
3
+ module VagrantPlugins
4
+ module CommandDns
5
+ module Command
6
+ module Host
7
+ class Destroy < Vagrant.plugin('2', :command)
8
+
9
+ def execute
10
+ options = {}
11
+ options[:skip] = false
12
+
13
+ opts = OptionParser.new do |o|
14
+ o.banner = 'Usage: vagrant dns host destroy'
15
+ o.separator ''
16
+ o.separator 'Options:'
17
+ o.separator ''
18
+
19
+ o.on('-s', '--skip', 'Skip ip check before record destruction. Use with extreme caution.') do |skip|
20
+ options[:skip] = skip
21
+ end
22
+
23
+ o.separator ''
24
+ o.separator 'Additional documentation can be found on the plugin homepage'
25
+ o.separator ''
26
+ end
27
+
28
+ argv = parse_options(opts)
29
+ return if !argv
30
+
31
+ with_target_vms(argv) do |machine|
32
+ machine.config.dns.__skip = options[:skip] if options[:skip]
33
+ @env.action_runner.run(Action::Host.host_destroy, {
34
+ machine: machine,
35
+ ui: Vagrant::UI::Prefixed.new(@env.ui, 'dns host'),
36
+ })
37
+ end
38
+
39
+ 0
40
+ end
41
+
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,74 @@
1
+ require 'optparse'
2
+
3
+ module VagrantPlugins
4
+ module CommandDns
5
+ module Command
6
+ module Host
7
+ class Root < Vagrant.plugin('2', :command)
8
+
9
+ def self.synopsis
10
+ 'manage host /etc/hosts dns records'
11
+ end
12
+
13
+ def initialize(argv, env)
14
+ super
15
+
16
+ @main_args, @sub_command, @sub_args = split_main_and_subcommand(argv)
17
+
18
+ @subcommands = Vagrant::Registry.new
19
+
20
+ @subcommands.register(:create) do
21
+ require_relative 'create'
22
+ Command::Host::Create
23
+ end
24
+
25
+ @subcommands.register(:destroy) do
26
+ require_relative 'destroy'
27
+ Command::Host::Destroy
28
+ end
29
+ end
30
+
31
+ def execute
32
+ if @main_args.include?('-h') || @main_args.include?('--help')
33
+ return help
34
+ end
35
+
36
+ # If we reached this far then we must have a subcommand. If not,
37
+ # then we also just print the help and exit.
38
+ command_class = @subcommands.get(@sub_command.to_sym) if @sub_command
39
+ return help if !command_class || !@sub_command
40
+ @logger.debug("Invoking command class: #{command_class} #{@sub_args.inspect}")
41
+
42
+ # Initialize and execute the command class
43
+ command_class.new(@sub_args, @env).execute
44
+ end
45
+
46
+ def help
47
+ opts = OptionParser.new do |opts|
48
+ opts.version = VagrantPlugins::CommandDns::VERSION
49
+ opts.banner = 'Usage: vagrant dns host <subcommand>'
50
+ opts.separator ''
51
+ opts.separator 'Available subcommands:'
52
+
53
+ # Add the available subcommands as separators in order to print them
54
+ # out as well.
55
+ keys = []
56
+ @subcommands.each { |key, value| keys << key.to_s }
57
+
58
+ keys.sort.each do |key|
59
+ opts.separator " #{key}"
60
+ end
61
+
62
+ opts.separator ''
63
+ opts.separator 'For help on any individual subcommand run `vagrant dns host <subcommand> -h`'
64
+ opts.separator ''
65
+ end
66
+
67
+ @env.ui.info(opts.help, prefix: false)
68
+ end
69
+
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,34 @@
1
+ require 'optparse'
2
+
3
+ module VagrantPlugins
4
+ module CommandDns
5
+ module Command
6
+ class IP < Vagrant.plugin('2', :command)
7
+
8
+ def execute
9
+ options = {}
10
+
11
+ opts = OptionParser.new do |o|
12
+ o.banner = 'Usage: vagrant dns ip'
13
+ o.separator ''
14
+ o.separator 'Additional documentation can be found on the plugin homepage'
15
+ o.separator ''
16
+ end
17
+
18
+ argv = parse_options(opts)
19
+ return if !argv
20
+
21
+ with_target_vms(argv) do |machine|
22
+ @env.action_runner.run(Action.show_ip, {
23
+ machine: machine,
24
+ ui: Vagrant::UI::Prefixed.new(@env.ui, 'dns'),
25
+ })
26
+ end
27
+
28
+ 0
29
+ end
30
+
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,77 @@
1
+ require 'optparse'
2
+
3
+ module VagrantPlugins
4
+ module CommandDns
5
+ module Command
6
+ class Root < Vagrant.plugin('2', :command)
7
+
8
+ def self.synopsis
9
+ 'manage dns records'
10
+ end
11
+
12
+ def initialize(argv, env)
13
+ super
14
+
15
+ @main_args, @sub_command, @sub_args = split_main_and_subcommand(argv)
16
+
17
+ @subcommands = Vagrant::Registry.new
18
+
19
+ @subcommands.register(:ip) do
20
+ require_relative 'ip'
21
+ IP
22
+ end
23
+
24
+ @subcommands.register(:host) do
25
+ require_relative 'host/root'
26
+ Host::Root
27
+ end
28
+
29
+ @subcommands.register(:route53) do
30
+ require_relative 'route53/root'
31
+ Route53::Root
32
+ end
33
+ end
34
+
35
+ def execute
36
+ if @main_args.include?('-h') || @main_args.include?('--help')
37
+ return help
38
+ end
39
+
40
+ # If we reached this far then we must have a subcommand. If not,
41
+ # then we also just print the help and exit.
42
+ command_class = @subcommands.get(@sub_command.to_sym) if @sub_command
43
+ return help if !command_class || !@sub_command
44
+ @logger.debug("Invoking command class: #{command_class} #{@sub_args.inspect}")
45
+
46
+ # Initialize and execute the command class
47
+ command_class.new(@sub_args, @env).execute
48
+ end
49
+
50
+ def help
51
+ opts = OptionParser.new do |opts|
52
+ opts.version = VagrantPlugins::CommandDns::VERSION
53
+ opts.banner = 'Usage: vagrant dns <subcommand>'
54
+ opts.separator ''
55
+ opts.separator 'Available subcommands:'
56
+
57
+ # Add the available subcommands as separators in order to print them
58
+ # out as well.
59
+ keys = []
60
+ @subcommands.each { |key, value| keys << key.to_s }
61
+
62
+ keys.sort.each do |key|
63
+ opts.separator " #{key}"
64
+ end
65
+
66
+ opts.separator ''
67
+ opts.separator 'For help on any individual subcommand run `vagrant dns <subcommand> -h`'
68
+ opts.separator ''
69
+ end
70
+
71
+ @env.ui.info(opts.help, prefix: false)
72
+ end
73
+
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,34 @@
1
+ require 'optparse'
2
+
3
+ module VagrantPlugins
4
+ module CommandDns
5
+ module Command
6
+ module Route53
7
+ class Create < Vagrant.plugin('2', :command)
8
+
9
+ def execute
10
+ opts = OptionParser.new do |o|
11
+ o.banner = 'Usage: vagrant dns route53 create'
12
+ o.separator ''
13
+ o.separator 'Additional documentation can be found on the plugin homepage'
14
+ o.separator ''
15
+ end
16
+
17
+ argv = parse_options(opts)
18
+ return if !argv
19
+
20
+ with_target_vms(argv) do |machine|
21
+ @env.action_runner.run(Action::Route53.route53_create, {
22
+ machine: machine,
23
+ ui: Vagrant::UI::Prefixed.new(@env.ui, 'dns route53'),
24
+ })
25
+ end
26
+
27
+ 0
28
+ end
29
+
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,46 @@
1
+ require 'optparse'
2
+
3
+ module VagrantPlugins
4
+ module CommandDns
5
+ module Command
6
+ module Route53
7
+ class Destroy < Vagrant.plugin('2', :command)
8
+
9
+ def execute
10
+ options = {}
11
+ options[:skip] = false
12
+
13
+ opts = OptionParser.new do |o|
14
+ o.banner = 'Usage: vagrant dns route53 destroy [options]'
15
+ o.separator ''
16
+ o.separator 'Options:'
17
+ o.separator ''
18
+
19
+ o.on('-s', '--skip', 'Skip ip check before record destruction. Use with extreme caution.') do |skip|
20
+ options[:skip] = skip
21
+ end
22
+
23
+ o.separator ''
24
+ o.separator 'Additional documentation can be found on the plugin homepage'
25
+ o.separator ''
26
+ end
27
+
28
+ argv = parse_options(opts)
29
+ return if !argv
30
+
31
+ with_target_vms(argv) do |machine|
32
+ machine.config.dns.__skip = options[:skip] if options[:skip]
33
+ @env.action_runner.run(Action::Route53.route53_destroy, {
34
+ machine: machine,
35
+ ui: Vagrant::UI::Prefixed.new(@env.ui, 'dns route53'),
36
+ })
37
+ end
38
+
39
+ 0
40
+ end
41
+
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,74 @@
1
+ require 'optparse'
2
+
3
+ module VagrantPlugins
4
+ module CommandDns
5
+ module Command
6
+ module Route53
7
+ class Root < Vagrant.plugin('2', :command)
8
+
9
+ def self.synopsis
10
+ 'manage route53 dns records'
11
+ end
12
+
13
+ def initialize(argv, env)
14
+ super
15
+
16
+ @main_args, @sub_command, @sub_args = split_main_and_subcommand(argv)
17
+
18
+ @subcommands = Vagrant::Registry.new
19
+
20
+ @subcommands.register(:create) do
21
+ require_relative 'create'
22
+ Command::Route53::Create
23
+ end
24
+
25
+ @subcommands.register(:destroy) do
26
+ require_relative 'destroy'
27
+ Command::Route53::Destroy
28
+ end
29
+ end
30
+
31
+ def execute
32
+ if @main_args.include?('-h') || @main_args.include?('--help')
33
+ return help
34
+ end
35
+
36
+ # If we reached this far then we must have a subcommand. If not,
37
+ # then we also just print the help and exit.
38
+ command_class = @subcommands.get(@sub_command.to_sym) if @sub_command
39
+ return help if !command_class || !@sub_command
40
+ @logger.debug("Invoking command class: #{command_class} #{@sub_args.inspect}")
41
+
42
+ # Initialize and execute the command class
43
+ command_class.new(@sub_args, @env).execute
44
+ end
45
+
46
+ def help
47
+ opts = OptionParser.new do |opts|
48
+ opts.version = VagrantPlugins::CommandDns::VERSION
49
+ opts.banner = 'Usage: vagrant dns route53 <subcommand>'
50
+ opts.separator ''
51
+ opts.separator 'Available subcommands:'
52
+
53
+ # Add the available subcommands as separators in order to print them
54
+ # out as well.
55
+ keys = []
56
+ @subcommands.each { |key, value| keys << key.to_s }
57
+
58
+ keys.sort.each do |key|
59
+ opts.separator " #{key}"
60
+ end
61
+
62
+ opts.separator ''
63
+ opts.separator 'For help on any individual subcommand run `vagrant dns route53 <subcommand> -h`'
64
+ opts.separator ''
65
+ end
66
+
67
+ @env.ui.info(opts.help, prefix: false)
68
+ end
69
+
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,90 @@
1
+ module VagrantPlugins
2
+ module CommandDns
3
+ class Config < Vagrant.plugin('2', :config)
4
+
5
+ # List of VM aliases in FQDN format
6
+ #
7
+ # @return [Array<String>]
8
+ attr_accessor :aliases
9
+
10
+ # AWS Route53 Settings
11
+
12
+ # The version of the AWS api to use
13
+ #
14
+ # @return [String]
15
+ attr_accessor :route53_version
16
+
17
+ # The access key ID for accessing AWS
18
+ #
19
+ # @return [String]
20
+ attr_accessor :route53_access_key_id
21
+
22
+ # The secret access key for accessing AWS
23
+ #
24
+ # @return [String]
25
+ attr_accessor :route53_secret_access_key
26
+
27
+ # The token associated with the key for accessing AWS
28
+ #
29
+ # @return [String]
30
+ attr_accessor :route53_session_token
31
+
32
+ # The Route53 Zone ID
33
+ #
34
+ # @return [String]
35
+ attr_accessor :route53_zone_id
36
+
37
+ attr_accessor :__skip
38
+ attr_reader :__available_providers
39
+
40
+ def initialize
41
+ @aliases = UNSET_VALUE
42
+
43
+ @route53_version = UNSET_VALUE
44
+ @route53_access_key_id = UNSET_VALUE
45
+ @route53_secret_access_key = UNSET_VALUE
46
+ @route53_session_token = UNSET_VALUE
47
+ @route53_zone_id = UNSET_VALUE
48
+
49
+ # Internal
50
+ @__skip = false
51
+ @__available_providers = %w(local route53)
52
+ end
53
+
54
+ def finalize!
55
+ @aliases = [] if @aliases == UNSET_VALUE
56
+
57
+ @route53_version = nil if @route53_version == UNSET_VALUE
58
+ @route53_zone_id = nil if @route53_zone_id == UNSET_VALUE
59
+
60
+ # Try to get access keys from standard AWS environment variables; they
61
+ # will default to nil if the environment variables are not present.
62
+ @route53_access_key_id = ENV['AWS_ACCESS_KEY'] if @route53_access_key_id == UNSET_VALUE
63
+ @route53_secret_access_key = ENV['AWS_SECRET_KEY'] if @route53_secret_access_key == UNSET_VALUE
64
+ @route53_session_token = ENV['AWS_SESSION_TOKEN'] if @route53_session_token == UNSET_VALUE
65
+ end
66
+
67
+ def validate(machine)
68
+ errors = _detected_errors
69
+
70
+ if @route53
71
+ if machine.provider_name == :aws
72
+ aws_config = machine.provider_config
73
+ # If these values are still not set and the AWS provider is being used, borrow it's config values
74
+ @route53_version = aws_config.version if @route53_version == nil
75
+ @route53_access_key_id = aws_config.access_key_id if @route53_access_key_id == nil
76
+ @route53_secret_access_key = aws_config.secret_access_key if @route53_secret_access_key == nil
77
+ @route53_session_token = aws_config.session_token if @route53_session_token == nil
78
+ end
79
+
80
+ errors << I18n.t('vagrant_command_dns.config.route53_zone_id_required') if @route53_zone_id.nil?
81
+ errors << I18n.t('vagrant_command_dns.config.route53_access_key_id_required') if @route53_access_key_id.nil?
82
+ errors << I18n.t('vagrant_command_dns.config.route53_secret_access_key_required') if @route53_secret_access_key.nil?
83
+ end
84
+
85
+ { 'DNS' => errors }
86
+ end
87
+
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,31 @@
1
+ module VagrantPlugins
2
+ module CommandDns
3
+ module Errors
4
+
5
+ class VagrantCommandDnsError < Vagrant::Errors::VagrantError
6
+ error_namespace('vagrant_command_dns.errors')
7
+ end
8
+
9
+ class MachineStateError < VagrantCommandDnsError
10
+ error_key(:machine_state_error)
11
+ end
12
+
13
+ class UnsupportedProviderError < VagrantCommandDnsError
14
+ error_key(:unsupported_provider_error)
15
+ end
16
+
17
+ class InvalidAddressError < VagrantCommandDnsError
18
+ error_key(:invalid_address_error)
19
+ end
20
+
21
+ class FogError < VagrantCommandDnsError
22
+ error_key(:fog_error)
23
+ end
24
+
25
+ class EditLocalHostsError < VagrantCommandDnsError
26
+ error_key(:edit_local_hosts_error)
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,69 @@
1
+ begin
2
+ require 'vagrant'
3
+ rescue LoadError
4
+ raise 'The Vagrant DNS Plugin must be run within Vagrant'
5
+ end
6
+
7
+ # This is a sanity check to make sure no one is attempting to install this
8
+ # into a Vagrant version earlier than it was developed on.
9
+ if Vagrant::VERSION < '1.7.4'
10
+ raise 'The Vagrant DNS Plugin is only compatible with Vagrant 1.7.4+'
11
+ end
12
+
13
+ module VagrantPlugins
14
+ module CommandDns
15
+ class Plugin < Vagrant.plugin('2')
16
+
17
+ name 'dns command'
18
+ description 'The `dns` command gives you a way to manage DNS records.'
19
+
20
+ # This initializes the internationalization strings.
21
+ def self.setup_i18n
22
+ I18n.load_path << File.expand_path('locales/en.yml', CommandDns.source_root)
23
+ I18n.reload!
24
+ end
25
+
26
+ # This sets up our log level to be whatever VAGRANT_LOG is.
27
+ def self.setup_logging
28
+ require 'log4r'
29
+
30
+ level = nil
31
+ begin
32
+ level = Log4r.const_get(ENV['VAGRANT_LOG'].upcase)
33
+ rescue NameError
34
+ # This means that the logging constant wasn't found,
35
+ # which is fine. We just keep `level` as `nil`. But
36
+ # we tell the user.
37
+ level = nil
38
+ end
39
+
40
+ # Some constants, such as "true" resolve to booleans, so the
41
+ # above error checking doesn't catch it. This will check to make
42
+ # sure that the log level is an integer, as Log4r requires.
43
+ level = nil if !level.is_a?(Integer)
44
+
45
+ # Set the logging level on all "vagrant" namespaced
46
+ # logs as long as we have a valid level.
47
+ if level
48
+ logger = Log4r::Logger.new('vagrant_command_dns')
49
+ logger.outputters = Log4r::Outputter.stderr
50
+ logger.level = level
51
+ logger = nil
52
+ end
53
+ end
54
+
55
+ config 'dns' do
56
+ setup_i18n
57
+ require_relative 'config'
58
+ Config
59
+ end
60
+
61
+ command 'dns' do
62
+ setup_logging
63
+ require_relative 'command/root'
64
+ Command::Root
65
+ end
66
+
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,5 @@
1
+ module VagrantPlugins
2
+ module CommandDns
3
+ VERSION = '0.1.0'
4
+ end
5
+ end
@@ -0,0 +1,20 @@
1
+ require 'pathname'
2
+ require 'vagrant-command-dns/version'
3
+ require 'vagrant-command-dns/plugin'
4
+
5
+ module VagrantPlugins
6
+ module CommandDns
7
+
8
+ lib_path = Pathname.new(File.expand_path('../vagrant-command-dns', __FILE__))
9
+ autoload :Action, lib_path.join('action')
10
+ autoload :Errors, lib_path.join('errors')
11
+
12
+ # This returns the path to the source of this plugin.
13
+ #
14
+ # @return [Pathname]
15
+ def self.source_root
16
+ @source_root ||= Pathname.new(File.expand_path('../../', __FILE__))
17
+ end
18
+
19
+ end
20
+ end
data/locales/en.yml ADDED
@@ -0,0 +1,43 @@
1
+ en:
2
+ vagrant_command_dns:
3
+
4
+ config:
5
+ route53_zone_id_required: |-
6
+ A zone ID must be specified via "route53_zone_id"
7
+ route53_access_key_id_required: |-
8
+ An access key ID must be specified via "route53_access_key_id"
9
+ route53_secret_access_key_required: |-
10
+ A secret access key is required via "route53_secret_access_key"
11
+
12
+ errors:
13
+ machine_state_error: |-
14
+ Machine must be %{state} to preform this action.
15
+ unsupported_provider_error: |-
16
+ Machine provider not supported. Pull requests and testers are welcome.
17
+ invalid_address_error: |-
18
+ invalid_address_error
19
+
20
+ command:
21
+ host:
22
+ edit_error: |-
23
+ Unable to edit /etc/hosts. Consult documentation or submit a pull request.
24
+ create_exists_match: |-
25
+ /etc/hosts record exists for %{ip} %{hostname}
26
+ create_exists_conflict: |-
27
+ this should be a friendly message telling them they have other conflicting entries to remove
28
+
29
+ route53:
30
+ fog_error: |-
31
+ AWS error: %{message}
32
+ create_success: |-
33
+ Route53 record created for %{ip} %{hostname}.
34
+ create_exists_match: |-
35
+ Route53 record exists for %{ip} %{hostname}.
36
+ create_exists_conflict: |-
37
+ Route53 record exists for %{ip} %{hostname}. Please update manually.
38
+ destroy_success: |-
39
+ Route53 record destroyed for %{hostname}
40
+ destroy_conflict: |-
41
+ Route53 record for %{hostname} does not match. Expected %{expected} got %{got}. Please update manually...
42
+ destroy_not_found: |-
43
+ Route53 record for %{hostname} not found. Skipping...
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'vagrant-command-dns/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'vagrant-command-dns'
8
+ spec.version = VagrantPlugins::CommandDns::VERSION
9
+ spec.authors = ['cornfeedhobo']
10
+ spec.email = ['cornfeedhobo@fuzzlabs.org']
11
+
12
+ spec.summary = %q{Vagrant Plugin to manage DNS records}
13
+ spec.homepage = 'https://github.com/cornfeedhobo/vagrant-command-dns'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.require_paths = ['lib']
18
+
19
+ spec.required_ruby_version = '>= 2.0'
20
+
21
+ spec.add_runtime_dependency 'fog', '~> 1.22'
22
+
23
+ spec.add_development_dependency 'bundler', '~> 1.10'
24
+ spec.add_development_dependency 'rake', '~> 10.0'
25
+ end