pax_global_header00006660000000000000000000000064127545027470014527gustar00rootroot0000000000000052 comment=2919623e0e910ddd8df697c8e03ebeda32ef24c2 vagrant-digitalocean-0.9.1/000077500000000000000000000000001275450274700156215ustar00rootroot00000000000000vagrant-digitalocean-0.9.1/.gitignore000066400000000000000000000002611275450274700176100ustar00rootroot00000000000000*.gem *.rbc .bundle .config .yardoc Gemfile.lock InstalledFiles _yardoc coverage doc/ lib/bundler/man pkg rdoc spec/reports test/tmp test/version_tmp test/.vagrant tmp .vagrant vagrant-digitalocean-0.9.1/Gemfile000066400000000000000000000003371275450274700171170ustar00rootroot00000000000000source 'https://rubygems.org' gem 'vagrant', :git => 'git://github.com/mitchellh/vagrant.git', :tag => 'v1.7.2' gem 'rake' group :plugins do gem 'vagrant-omnibus' gem 'vagrant-digitalocean', :path => '.' end gemspec vagrant-digitalocean-0.9.1/LICENSE.txt000066400000000000000000000021141275450274700174420ustar00rootroot00000000000000Copyright (c) 2013 John Bender Copyright (c) 2013 Shawn Dahlen MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. vagrant-digitalocean-0.9.1/README.md000066400000000000000000000222161275450274700171030ustar00rootroot00000000000000DigitalOcean Vagrant Provider ============================== [![Gem](https://img.shields.io/gem/v/vagrant-digitalocean.svg)](https://rubygems.org/gems/vagrant-digitalocean) [![Gem](https://img.shields.io/gem/dt/vagrant-digitalocean.svg)](https://rubygems.org/gems/vagrant-digitalocean) [![Gem](https://img.shields.io/gem/dtv/vagrant-digitalocean.svg)](https://rubygems.org/gems/vagrant-digitalocean) [![Twitter](https://img.shields.io/twitter/url/https/github.com/devopsgroup-io/vagrant-digitalocean.svg?style=social)](https://twitter.com/intent/tweet?text=Check%20out%20this%20awesome%20Vagrant%20plugin%21&url=https%3A%2F%2Fgithub.com%2Fdevopsgroup-io%2Fvagrant-digitalocean&hashtags=vagrant%2Cdigitalocean&original_referer=) `vagrant-digitalocean` is a Vagrant provider plugin that supports the management of [DigitalOcean](https://www.digitalocean.com/) droplets (instances). Features include: - create and destroy droplets - power on and off droplets - rebuild a droplet (destroys and ups with same IP address) - provision a droplet with shell - setup a SSH public key for authentication - create a new user account during droplet creation Install ------- Install the provider plugin using the Vagrant command-line interface: `vagrant plugin install vagrant-digitalocean` Configure --------- Once the provider has been installed, you will need to configure your project to use it. The most basic `Vagrantfile` to create a droplet on DigitalOcean is shown below: ```ruby Vagrant.configure('2') do |config| config.vm.hostname = 'dropletname.example.com' # Alternatively, use provider.name below to set the Droplet name. config.vm.hostname takes precedence. config.vm.provider :digital_ocean do |provider, override| override.ssh.private_key_path = '~/.ssh/id_rsa' override.vm.box = 'digital_ocean' override.vm.box_url = "https://github.com/devopsgroup-io/vagrant-digitalocean/raw/master/box/digital_ocean.box" provider.token = 'YOUR TOKEN' provider.image = 'ubuntu-14-04-x64' provider.region = 'nyc2' provider.size = '512mb' end end ``` **Configuration Requirements** - You *must* specify the `override.ssh.private_key_path` to enable authentication with the droplet. The provider will create a new DigitalOcean SSH key using your public key which is assumed to be the `private_key_path` with a *.pub* extension. - You *must* specify your DigitalOcean Personal Access Token at `provider.token`. This may be found on the control panel within the *Apps & API* section. **Supported Configuration Attributes** The following attributes are available to further configure the provider: - `provider.image` * A string representing the image to use when creating a new droplet. It defaults to `ubuntu-14-04-x64`. List available images with the `vagrant digitalocean-list images $DIGITAL_OCEAN_TOKEN` command. Like when using the DigitalOcean API directly, [it can be an image ID or slug](https://developers.digitalocean.com/documentation/v2/#create-a-new-droplet). - `provider.ipv6` * A boolean flag indicating whether to enable IPv6 - `provider.region` * A string representing the region to create the new droplet in. It defaults to `nyc2`. List available regions with the `vagrant digitalocean-list regions $DIGITAL_OCEAN_TOKEN` command. - `provider.size` * A string representing the size to use when creating a new droplet (e.g. `1gb`). It defaults to `512mb`. List available sizes with the `vagrant digitalocean-list sizes $DIGITAL_OCEAN_TOKEN` command. - `provider.private_networking` * A boolean flag indicating whether to enable a private network interface (if the region supports private networking). It defaults to `false`. - `provider.backups_enabled` * A boolean flag indicating whether to enable backups for the droplet. It defaults to `false`. - `provider.ssh_key_name` * A string representing the name to use when creating a DigitalOcean SSH key for droplet authentication. It defaults to `Vagrant`. - `provider.setup` * A boolean flag indicating whether to setup a new user account and modify sudo to disable tty requirement. It defaults to `true`. If you are using a tool like [Packer](https://packer.io) to create reusable snapshots with user accounts already provisioned, set to `false`. - `config.vm.synced_folder` * Supports both rsync__args and rsync__exclude, see the [Vagrant Docs](http://docs.vagrantup.com/v2/synced-folders/rsync.html) for more information. rsync__args default to `["--verbose", "--archive", "--delete", "-z", "--copy-links"]` and rsync__exclude defaults to `[".vagrant/"]`. The provider will create a new user account with the specified SSH key for authorization if `config.ssh.username` is set and the `provider.setup` attribute is `true`. Run --- After creating your project's `Vagrantfile` with the required configuration attributes described above, you may create a new droplet with the following command: $ vagrant up --provider=digital_ocean This command will create a new droplet, setup your SSH key for authentication, create a new user account, and run the provisioners you have configured. **Supported Commands** The provider supports the following Vagrant sub-commands: - `vagrant destroy` - Destroys the droplet instance. - `vagrant ssh` - Logs into the droplet instance using the configured user account. - `vagrant halt` - Powers off the droplet instance. - `vagrant provision` - Runs the configured provisioners and rsyncs any specified `config.vm.synced_folder`. - `vagrant reload` - Reboots the droplet instance. - `vagrant rebuild` - Destroys the droplet instance and recreates it with the same IP address which was previously assigned. - `vagrant status` - Outputs the status (active, off, not created) for the droplet instance. Compatability ------------- This [DigitalOcean API](https://developers.digitalocean.com/documentation/changelog/) provider plugin for Vagrant has been tested with the following technology. Date Tested | Vagrant Version | vagrant-digitalocean Version | Host (Workstation) Operating System | Guest (DigitalOcean) Operating System ------------|-----------------|------------------------------|-----------------------|-------------------------------------- 03/22/2016 | 1.8.1 | 0.7.10 | OS X 10.11.4 | CentOS 7.0 04/03/2013 | 1.1.5 | 0.1.0 | Ubuntu 12.04 | CentOS 6.3 Troubleshooting --------------- Before submitting a GitHub issue, please ensure both Vagrant and vagrant-digitalocean are fully up-to-date. * For the latest Vagrant version, please visit the [Vagrant](https://www.vagrantup.com/) website * To update Vagrant plugins, run the following command: `vagrant plugin update` * `vagrant plugin install vagrant-digitalocean` * Installation on OS X may not working due to a SSL certificate problem, and you may need to specify a certificate path explicitly. To do so, run `ruby -ropenssl -e "p OpenSSL::X509::DEFAULT_CERT_FILE"`. Then, add the following environment variable to your `.bash_profile` script and `source` it: `export SSL_CERT_FILE=/usr/local/etc/openssl/cert.pem`. FAQ --- * The Chef provisioner is no longer supported by default (as of 0.2.0). Please use the `vagrant-omnibus` plugin to install Chef on Vagrant-managed machines. This plugin provides control over the specific version of Chef to install. Contribute ---------- To contribute, fork then clone the repository, and then the following: **Developing** 1. Install [Bundler](http://bundler.io/) 2. Currently the Bundler version is locked to 1.7.9, please install this version. * `sudo gem install bundler -v '1.7.9'` 3. Then install vagrant-digitalocean dependancies: * `bundle _1.7.9_ install` 4. Do your development and run a few commands, one to get started would be: * `bundle _1.7.9_ exec vagrant digitalocean-list images` 5. You can then run a test: * `bundle _1.7.9_ exec rake test` 6. Once you are satisfied with your changes, please submit a pull request. **Testing** 1. Build and package your newly developed code: * `rake gem:build` 2. Then install the packaged plugin: * `vagrant plugin install pkg/vagrant-digitalocean-*.gem` 3. Once you're done testing, roll-back to the latest released version: * `vagrant plugin uninstall vagrant-digitalocean` * `vagrant plugin install vagrant-digitalocean` 4. Once you're satisfied developing and testing your new code, please submit a pull request for review. **Releasing** To release a new version of vagrant-digitalocean you will need to do the following: *(only contributors of the GitHub repo and owners of the project at RubyGems will have rights to do this)* 1. First, bump the version in ~/lib/vagrant-digitalocean/version.rb: * Follow [Semantic Versioning](http://semver.org/). 2. Then, create a matching GitHub Release (this will also create a tag): * Preface the version number with a `v`. * https://github.com/devopsgroup-io/vagrant-digitalocean/releases 3. You will then need to build and push the new gem to RubyGems: * `rake gem:build` * `gem push pkg/vagrant-digitalocean-0.7.6.gem` 4. Then, when John Doe runs the following, they will receive the updated vagrant-digitalocean plugin: * `vagrant plugin update` * `vagrant plugin update vagrant-digitalocean` vagrant-digitalocean-0.9.1/Rakefile000066400000000000000000000005411275450274700172660ustar00rootroot00000000000000require 'bundler/gem_helper' namespace :gem do Bundler::GemHelper.install_tasks end task :test do result = sh 'bash test/test.sh' if result puts 'Success!' else puts 'Failure!' exit 1 end end def env ['DO_CLIENT_ID', 'DO_API_KEY', 'VAGRANT_LOG'].inject('') do |acc, key| acc += "#{key}=#{ENV[key] || 'error'} " end end vagrant-digitalocean-0.9.1/box/000077500000000000000000000000001275450274700164115ustar00rootroot00000000000000vagrant-digitalocean-0.9.1/box/digital_ocean.box000066400000000000000000000002571275450274700217110ustar00rootroot00000000000000eQK 0Ꮋ$܌jiqV Dor\.&[4!:C&sPJ֊{LB*7*/Ҷ&j6/NCtXehceetx柸Bcߝ+zW*zmkezuA[7ǜq(vagrant-digitalocean-0.9.1/box/metadata.json000066400000000000000000000000411275450274700210570ustar00rootroot00000000000000{ "provider": "digital_ocean" }vagrant-digitalocean-0.9.1/lib/000077500000000000000000000000001275450274700163675ustar00rootroot00000000000000vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean.rb000066400000000000000000000010361275450274700227770ustar00rootroot00000000000000require 'vagrant-digitalocean/version' require 'vagrant-digitalocean/plugin' require 'vagrant-digitalocean/errors' module VagrantPlugins module DigitalOcean def self.source_root @source_root ||= Pathname.new(File.expand_path('../../', __FILE__)) end def self.public_key(private_key_path) File.read("#{private_key_path}.pub") rescue raise Errors::PublicKeyError, :path => "#{private_key_path}.pub" end I18n.load_path << File.expand_path('locales/en.yml', source_root) I18n.reload! end end vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/000077500000000000000000000000001275450274700224525ustar00rootroot00000000000000vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/actions.rb000066400000000000000000000122001275450274700244320ustar00rootroot00000000000000require 'vagrant-digitalocean/actions/check_state' require 'vagrant-digitalocean/actions/create' require 'vagrant-digitalocean/actions/destroy' require 'vagrant-digitalocean/actions/shut_down' require 'vagrant-digitalocean/actions/power_off' require 'vagrant-digitalocean/actions/power_on' require 'vagrant-digitalocean/actions/rebuild' require 'vagrant-digitalocean/actions/reload' require 'vagrant-digitalocean/actions/setup_user' require 'vagrant-digitalocean/actions/setup_sudo' require 'vagrant-digitalocean/actions/setup_key' require 'vagrant-digitalocean/actions/modify_provision_path' module VagrantPlugins module DigitalOcean module Actions include Vagrant::Action::Builtin def self.destroy return Vagrant::Action::Builder.new.tap do |builder| builder.use ConfigValidate builder.use Call, CheckState do |env, b| case env[:machine_state] when :not_created env[:ui].info I18n.t('vagrant_digital_ocean.info.not_created') else b.use Call, DestroyConfirm do |env2, b2| if env2[:result] b2.use Destroy b2.use ProvisionerCleanup if defined?(ProvisionerCleanup) end end end end end end def self.ssh return Vagrant::Action::Builder.new.tap do |builder| builder.use ConfigValidate builder.use Call, CheckState do |env, b| case env[:machine_state] when :active b.use SSHExec when :off env[:ui].info I18n.t('vagrant_digital_ocean.info.off') when :not_created env[:ui].info I18n.t('vagrant_digital_ocean.info.not_created') end end end end def self.ssh_run return Vagrant::Action::Builder.new.tap do |builder| builder.use ConfigValidate builder.use Call, CheckState do |env, b| case env[:machine_state] when :active b.use SSHRun when :off env[:ui].info I18n.t('vagrant_digital_ocean.info.off') when :not_created env[:ui].info I18n.t('vagrant_digital_ocean.info.not_created') end end end end def self.provision return Vagrant::Action::Builder.new.tap do |builder| builder.use ConfigValidate builder.use Call, CheckState do |env, b| case env[:machine_state] when :active b.use Provision b.use ModifyProvisionPath b.use SyncedFolders when :off env[:ui].info I18n.t('vagrant_digital_ocean.info.off') when :not_created env[:ui].info I18n.t('vagrant_digital_ocean.info.not_created') end end end end def self.up return Vagrant::Action::Builder.new.tap do |builder| builder.use ConfigValidate builder.use Call, CheckState do |env, b| case env[:machine_state] when :active env[:ui].info I18n.t('vagrant_digital_ocean.info.already_active') when :off b.use PowerOn b.use provision when :not_created b.use SetupKey b.use Create b.use SetupSudo b.use SetupUser b.use provision end end end end def self.halt return Vagrant::Action::Builder.new.tap do |builder| builder.use ConfigValidate builder.use Call, CheckState do |env, b| case env[:machine_state] when :active if env[:force_halt] b.use PowerOff else b.use ShutDown end when :off env[:ui].info I18n.t('vagrant_digital_ocean.info.already_off') when :not_created env[:ui].info I18n.t('vagrant_digital_ocean.info.not_created') end end end end def self.reload return Vagrant::Action::Builder.new.tap do |builder| builder.use ConfigValidate builder.use Call, CheckState do |env, b| case env[:machine_state] when :active b.use Reload b.use provision when :off env[:ui].info I18n.t('vagrant_digital_ocean.info.off') when :not_created env[:ui].info I18n.t('vagrant_digital_ocean.info.not_created') end end end end def self.rebuild return Vagrant::Action::Builder.new.tap do |builder| builder.use ConfigValidate builder.use Call, CheckState do |env, b| case env[:machine_state] when :active, :off b.use Rebuild b.use SetupSudo b.use SetupUser b.use provision when :not_created env[:ui].info I18n.t('vagrant_digital_ocean.info.not_created') end end end end end end end vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/actions/000077500000000000000000000000001275450274700241125ustar00rootroot00000000000000vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/actions/check_state.rb000066400000000000000000000007221275450274700267150ustar00rootroot00000000000000module VagrantPlugins module DigitalOcean module Actions class CheckState def initialize(app, env) @app = app @machine = env[:machine] @logger = Log4r::Logger.new('vagrant::digitalocean::check_state') end def call(env) env[:machine_state] = @machine.state.id @logger.info "Machine state is '#{@machine.state.id}'" @app.call(env) end end end end end vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/actions/create.rb000066400000000000000000000061611275450274700257060ustar00rootroot00000000000000require 'vagrant-digitalocean/helpers/client' module VagrantPlugins module DigitalOcean module Actions class Create include Helpers::Client include Vagrant::Util::Retryable def initialize(app, env) @app = app @machine = env[:machine] @client = client @logger = Log4r::Logger.new('vagrant::digitalocean::create') end def call(env) ssh_key_id = [env[:ssh_key_id]] # submit new droplet request result = @client.post('/v2/droplets', { :size => @machine.provider_config.size, :region => @machine.provider_config.region, :image => @machine.provider_config.image, :name => @machine.config.vm.hostname || @machine.name, :ssh_keys => ssh_key_id, :private_networking => @machine.provider_config.private_networking, :backups => @machine.provider_config.backups_enabled, :ipv6 => @machine.provider_config.ipv6, :user_data => @machine.provider_config.user_data }.delete_if { |k, v| v.nil? }) # wait for request to complete env[:ui].info I18n.t('vagrant_digital_ocean.info.creating') @client.wait_for_event(env, result['links']['actions'].first['id']) # assign the machine id for reference in other commands @machine.id = result['droplet']['id'].to_s # refresh droplet state with provider and output ip address droplet = Provider.droplet(@machine, :refresh => true) public_network = droplet['networks']['v4'].find { |network| network['type'] == 'public' } private_network = droplet['networks']['v4'].find { |network| network['type'] == 'private' } env[:ui].info I18n.t('vagrant_digital_ocean.info.droplet_ip', { :ip => public_network['ip_address'] }) if private_network env[:ui].info I18n.t('vagrant_digital_ocean.info.droplet_private_ip', { :ip => private_network['ip_address'] }) end # wait for ssh to be ready switch_user = @machine.provider_config.setup? user = @machine.config.ssh.username @machine.config.ssh.username = 'root' if switch_user retryable(:tries => 120, :sleep => 10) do next if env[:interrupted] raise 'not ready' if !@machine.communicate.ready? end @machine.config.ssh.username = user @app.call(env) end # Both the recover and terminate are stolen almost verbatim from # the Vagrant AWS provider up action def recover(env) return if env['vagrant.error'].is_a?(Vagrant::Errors::VagrantError) if @machine.state.id != :not_created terminate(env) end end def terminate(env) destroy_env = env.dup destroy_env.delete(:interrupted) destroy_env[:config_validate] = false destroy_env[:force_confirm_destroy] = true env[:action_runner].run(Actions.destroy, destroy_env) end end end end end vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/actions/destroy.rb000066400000000000000000000013221275450274700261260ustar00rootroot00000000000000require 'vagrant-digitalocean/helpers/client' module VagrantPlugins module DigitalOcean module Actions class Destroy include Helpers::Client def initialize(app, env) @app = app @machine = env[:machine] @client = client @logger = Log4r::Logger.new('vagrant::digitalocean::destroy') end def call(env) # submit destroy droplet request @client.delete("/v2/droplets/#{@machine.id}") env[:ui].info I18n.t('vagrant_digital_ocean.info.destroying') # set the machine id to nil to cleanup local vagrant state @machine.id = nil @app.call(env) end end end end end vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/actions/modify_provision_path.rb000066400000000000000000000022731275450274700310560ustar00rootroot00000000000000module VagrantPlugins module DigitalOcean module Actions class ModifyProvisionPath def initialize(app, env) @app = app @machine = env[:machine] @logger = Log4r::Logger.new('vagrant::digitalocean::modify_provision_path') end def call(env) # check if provisioning is enabled enabled = true enabled = env[:provision_enabled] if env.has_key?(:provision_enabled) return @app.call(env) if !enabled username = @machine.ssh_info()[:username] # change ownership of the provisioning path recursively to the # ssh user # # TODO submit patch to vagrant to set appropriate permissions # based on ssh username @machine.config.vm.provisioners.each do |provisioner| cfg = provisioner.config path = cfg.upload_path if cfg.respond_to? :upload_path path = cfg.provisioning_path if cfg.respond_to? :provisioning_path @machine.communicate.sudo("chown -R #{username} #{path}", :error_check => false) end @app.call(env) end end end end end vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/actions/power_off.rb000066400000000000000000000016241275450274700264300ustar00rootroot00000000000000require 'vagrant-digitalocean/helpers/client' #TODO: --force module VagrantPlugins module DigitalOcean module Actions class PowerOff include Helpers::Client def initialize(app, env) @app = app @machine = env[:machine] @client = client @logger = Log4r::Logger.new('vagrant::digitalocean::power_off') end def call(env) # submit power off droplet request result = @client.post("/v2/droplets/#{@machine.id}/actions", { :type => 'power_off' }) # wait for request to complete env[:ui].info I18n.t('vagrant_digital_ocean.info.powering_off') @client.wait_for_event(env, result['action']['id']) # refresh droplet state with provider Provider.droplet(@machine, :refresh => true) @app.call(env) end end end end end vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/actions/power_on.rb000066400000000000000000000016031275450274700262670ustar00rootroot00000000000000require 'vagrant-digitalocean/helpers/client' module VagrantPlugins module DigitalOcean module Actions class PowerOn include Helpers::Client def initialize(app, env) @app = app @machine = env[:machine] @client = client @logger = Log4r::Logger.new('vagrant::digitalocean::power_on') end def call(env) # submit power on droplet request result = @client.post("/v2/droplets/#{@machine.id}/actions", { :type => 'power_on' }) # wait for request to complete env[:ui].info I18n.t('vagrant_digital_ocean.info.powering_on') @client.wait_for_event(env, result['action']['id']) # refresh droplet state with provider Provider.droplet(@machine, :refresh => true) @app.call(env) end end end end end vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/actions/rebuild.rb000066400000000000000000000025651275450274700260750ustar00rootroot00000000000000require 'vagrant-digitalocean/helpers/client' module VagrantPlugins module DigitalOcean module Actions class Rebuild include Helpers::Client include Vagrant::Util::Retryable def initialize(app, env) @app = app @machine = env[:machine] @client = client @logger = Log4r::Logger.new('vagrant::digitalocean::rebuild') end def call(env) # submit rebuild request result = @client.post("/v2/droplets/#{@machine.id}/actions", { :type => 'rebuild', :image => @machine.provider_config.image }) # wait for request to complete env[:ui].info I18n.t('vagrant_digital_ocean.info.rebuilding') @client.wait_for_event(env, result['action']['id']) # refresh droplet state with provider Provider.droplet(@machine, :refresh => true) # wait for ssh to be ready switch_user = @machine.provider_config.setup? user = @machine.config.ssh.username @machine.config.ssh.username = 'root' if switch_user retryable(:tries => 120, :sleep => 10) do next if env[:interrupted] raise 'not ready' if !@machine.communicate.ready? end @machine.config.ssh.username = user @app.call(env) end end end end end vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/actions/reload.rb000066400000000000000000000014211275450274700257030ustar00rootroot00000000000000require 'vagrant-digitalocean/helpers/client' module VagrantPlugins module DigitalOcean module Actions class Reload include Helpers::Client def initialize(app, env) @app = app @machine = env[:machine] @client = client @logger = Log4r::Logger.new('vagrant::digitalocean::reload') end def call(env) # submit reboot droplet request result = @client.post("/v2/droplets/#{@machine.id}/actions", { :type => 'reboot' }) # wait for request to complete env[:ui].info I18n.t('vagrant_digital_ocean.info.reloading') @client.wait_for_event(env, result['action']['id']) @app.call(env) end end end end end vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/actions/setup_key.rb000066400000000000000000000032611275450274700264510ustar00rootroot00000000000000require 'vagrant-digitalocean/helpers/client' module VagrantPlugins module DigitalOcean module Actions class SetupKey include Helpers::Client def initialize(app, env) @app = app @machine = env[:machine] @client = client @logger = Log4r::Logger.new('vagrant::digitalocean::setup_key') end # TODO check the content of the key to see if it has changed def call(env) ssh_key_name = @machine.provider_config.ssh_key_name begin # assigns existing ssh key id to env for use by other commands env[:ssh_key_id] = @client .request('/v2/account/keys') .find_id(:ssh_keys, :name => ssh_key_name) env[:ui].info I18n.t('vagrant_digital_ocean.info.using_key', { :name => ssh_key_name }) rescue Errors::ResultMatchError env[:ssh_key_id] = create_ssh_key(ssh_key_name, env) end @app.call(env) end private def create_ssh_key(name, env) # assumes public key exists on the same path as private key with .pub ext path = @machine.config.ssh.private_key_path path = path[0] if path.is_a?(Array) path = File.expand_path(path, @machine.env.root_path) pub_key = DigitalOcean.public_key(path) env[:ui].info I18n.t('vagrant_digital_ocean.info.creating_key', { :name => name }) result = @client.post('/v2/account/keys', { :name => name, :public_key => pub_key }) result['ssh_key']['id'] end end end end end vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/actions/setup_sudo.rb000066400000000000000000000030451275450274700266330ustar00rootroot00000000000000module VagrantPlugins module DigitalOcean module Actions class SetupSudo def initialize(app, env) @app = app @machine = env[:machine] @logger = Log4r::Logger.new('vagrant::digitalocean::setup_sudo') end def call(env) # check if setup is enabled return @app.call(env) unless @machine.provider_config.setup? # override ssh username to root user = @machine.config.ssh.username @machine.config.ssh.username = 'root' # check for guest name available in Vagrant 1.2 first guest_name = @machine.guest.name if @machine.guest.respond_to?(:name) guest_name ||= @machine.guest.to_s.downcase case guest_name when /debian/ if @machine.provider_config.image =~ /^debian-8/ env[:ui].info I18n.t('vagrant_digital_ocean.info.late_sudo_install_deb8') @machine.communicate.execute(<<-'BASH') if [ ! -x /usr/bin/sudo ] ; then apt-get update -y && apt-get install -y sudo ; fi BASH end when /redhat/ env[:ui].info I18n.t('vagrant_digital_ocean.info.modifying_sudo') # disable tty requirement for sudo @machine.communicate.execute(<<-'BASH') sed -i'.bk' -e 's/\(Defaults\s\+requiretty\)/# \1/' /etc/sudoers BASH end # reset ssh username @machine.config.ssh.username = user @app.call(env) end end end end end vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/actions/setup_user.rb000066400000000000000000000042031275450274700266340ustar00rootroot00000000000000module VagrantPlugins module DigitalOcean module Actions class SetupUser def initialize(app, env) @app = app @machine = env[:machine] @logger = Log4r::Logger.new('vagrant::digitalocean::setup_user') end def call(env) # check if setup is enabled return @app.call(env) unless @machine.provider_config.setup? # check if a username has been specified return @app.call(env) unless @machine.config.ssh.username # override ssh username to root temporarily user = @machine.config.ssh.username @machine.config.ssh.username = 'root' env[:ui].info I18n.t('vagrant_digital_ocean.info.creating_user', { :user => user }) # create user account @machine.communicate.execute(<<-BASH) if ! (grep ^#{user}: /etc/passwd); then useradd -m -s /bin/bash #{user}; fi BASH # grant user sudo access with no password requirement @machine.communicate.execute(<<-BASH) if ! (grep #{user} /etc/sudoers); then echo "#{user} ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers; else sed -i -e "/#{user}/ s/=.*/=(ALL:ALL) NOPASSWD: ALL/" /etc/sudoers; fi BASH # create the .ssh directory in the users home @machine.communicate.execute("su #{user} -c 'mkdir -p ~/.ssh'") # add the specified key to the authorized keys file path = @machine.config.ssh.private_key_path path = path[0] if path.is_a?(Array) path = File.expand_path(path, @machine.env.root_path) pub_key = DigitalOcean.public_key(path) @machine.communicate.execute(<<-BASH) if ! grep '#{pub_key}' /home/#{user}/.ssh/authorized_keys; then echo '#{pub_key}' >> /home/#{user}/.ssh/authorized_keys; fi chown -R #{user} /home/#{user}/.ssh; BASH # reset username @machine.config.ssh.username = user @app.call(env) end end end end end vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/actions/shut_down.rb000066400000000000000000000016051275450274700264530ustar00rootroot00000000000000require 'vagrant-digitalocean/helpers/client' module VagrantPlugins module DigitalOcean module Actions class ShutDown include Helpers::Client def initialize(app, env) @app = app @machine = env[:machine] @client = client @logger = Log4r::Logger.new('vagrant::digitalocean::shut_down') end def call(env) # submit shutdown droplet request result = @client.post("/v2/droplets/#{@machine.id}/actions", { :type => 'shutdown' }) # wait for request to complete env[:ui].info I18n.t('vagrant_digital_ocean.info.shutting_down') @client.wait_for_event(env, result['action']['id']) # refresh droplet state with provider Provider.droplet(@machine, :refresh => true) @app.call(env) end end end end end vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/commands/000077500000000000000000000000001275450274700242535ustar00rootroot00000000000000vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/commands/list.rb000066400000000000000000000060761275450274700255640ustar00rootroot00000000000000require 'optparse' require 'vagrant-digitalocean/helpers/client' module VagrantPlugins module DigitalOcean module Commands class List < Vagrant.plugin('2', :command) def self.synopsis "list available images and regions from DigitalOcean" end def execute @token = nil @opts = OptionParser.new do |o| o.banner = 'Usage: vagrant digitalocean-list [options] ' o.on("-r", "--[no-]regions", "show the regions when listing images") do |r| @regions = r end end argv = parse_options(@opts) @token = argv[1] if @token.nil? usage return 1 end case argv[0] when "images" result = query('/v2/images') images = Array(result["images"]) if @regions images_table = images.map do |image| '%-50s %-20s %-20s %-50s' % ["#{image['distribution']} #{image['name']}", image['slug'], image['id'], image['regions'].join(', ')] end @env.ui.info I18n.t('vagrant_digital_ocean.info.images_with_regions', images: images_table.sort.join("\r\n")) else images_table = images.map do |image| '%-50s %-30s %-30s' % ["#{image['distribution']} #{image['name']}", image['slug'], image['id']] end @env.ui.info I18n.t('vagrant_digital_ocean.info.images', images: images_table.sort.join("\r\n")) end when "regions" result = query('/v2/regions') regions = Array(result["regions"]) regions_table = regions.map { |region| '%-30s %-12s' % [region['name'], region['slug']] } @env.ui.info I18n.t('vagrant_digital_ocean.info.regions', regions: regions_table.sort.join("\r\n")) when "sizes" result = query('/v2/sizes') sizes = Array(result["sizes"]) sizes_table = sizes.map { |size| '%-15s %-15s %-12s' % ["#{size['memory']}MB", size['vcpus'], size['slug']] } @env.ui.info I18n.t('vagrant_digital_ocean.info.sizes', sizes: sizes_table.sort_by{|s| s['memory']}.join("\r\n")) else usage return 1 end 0 rescue Faraday::Error::ConnectionFailed, RuntimeError => e @env.ui.error I18n.t('vagrant_digital_ocean.info.list_error', message: e.message) 1 end def query(path) connection = Faraday.new({ :url => "https://api.digitalocean.com/" }) result = connection.get(path, per_page: 100) do |req| req.headers['Authorization'] = "Bearer #{@token}" end case result.status when 200 then JSON.parse(result.body) when 401 then raise("unauthorized access — is the token correct?") else raise("call returned with status #{result.status}") end end def usage @env.ui.info(@opts) end end end end end vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/commands/rebuild.rb000066400000000000000000000012211275450274700262220ustar00rootroot00000000000000require 'optparse' module VagrantPlugins module DigitalOcean module Commands class Rebuild < Vagrant.plugin('2', :command) # Show description when `vagrant list-commands` is triggered def self.synopsis "plugin: vagrant-digitalocean: destroys and ups the vm with the same ip address" end def execute opts = OptionParser.new do |o| o.banner = 'Usage: vagrant rebuild [vm-name]' end argv = parse_options(opts) with_target_vms(argv) do |machine| machine.action(:rebuild) end 0 end end end end end vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/config.rb000066400000000000000000000044001275450274700242420ustar00rootroot00000000000000module VagrantPlugins module DigitalOcean class Config < Vagrant.plugin('2', :config) attr_accessor :token attr_accessor :image attr_accessor :region attr_accessor :size attr_accessor :private_networking attr_accessor :ipv6 attr_accessor :backups_enabled attr_accessor :ca_path attr_accessor :ssh_key_name attr_accessor :setup attr_accessor :user_data alias_method :setup?, :setup def initialize @token = UNSET_VALUE @image = UNSET_VALUE @region = UNSET_VALUE @size = UNSET_VALUE @private_networking = UNSET_VALUE @ipv6 = UNSET_VALUE @backups_enable = UNSET_VALUE @ca_path = UNSET_VALUE @ssh_key_name = UNSET_VALUE @setup = UNSET_VALUE @user_data = UNSET_VALUE end def finalize! @token = ENV['DO_TOKEN'] if @token == UNSET_VALUE @image = 'ubuntu-14-04-x64' if @image == UNSET_VALUE @region = 'nyc2' if @region == UNSET_VALUE @size = '512mb' if @size == UNSET_VALUE @private_networking = false if @private_networking == UNSET_VALUE @ipv6 = false if @ipv6 == UNSET_VALUE @backups_enabled = false if @backups_enabled == UNSET_VALUE @ca_path = nil if @ca_path == UNSET_VALUE @ssh_key_name = 'Vagrant' if @ssh_key_name == UNSET_VALUE @setup = true if @setup == UNSET_VALUE @user_data = nil if @user_data == UNSET_VALUE end def validate(machine) errors = [] errors << I18n.t('vagrant_digital_ocean.config.token') if !@token key = machine.config.ssh.private_key_path key = key[0] if key.is_a?(Array) if !key errors << I18n.t('vagrant_digital_ocean.config.private_key') elsif !File.file?(File.expand_path("#{key}.pub", machine.env.root_path)) errors << I18n.t('vagrant_digital_ocean.config.public_key', { :key => "#{key}.pub" }) end { 'DigitalOcean Provider' => errors } end end end end vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/errors.rb000066400000000000000000000014561275450274700243210ustar00rootroot00000000000000module VagrantPlugins module DigitalOcean module Errors class DigitalOceanError < Vagrant::Errors::VagrantError error_namespace("vagrant_digital_ocean.errors") end class APIStatusError < DigitalOceanError error_key(:api_status) end class JSONError < DigitalOceanError error_key(:json) end class ResultMatchError < DigitalOceanError error_key(:result_match) end class CertificateError < DigitalOceanError error_key(:certificate) end class LocalIPError < DigitalOceanError error_key(:local_ip) end class PublicKeyError < DigitalOceanError error_key(:public_key) end class RsyncError < DigitalOceanError error_key(:rsync) end end end end vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/helpers/000077500000000000000000000000001275450274700241145ustar00rootroot00000000000000vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/helpers/client.rb000066400000000000000000000062631275450274700257260ustar00rootroot00000000000000require 'vagrant-digitalocean/helpers/result' require 'faraday' require 'json' module VagrantPlugins module DigitalOcean module Helpers module Client def client @client ||= ApiClient.new(@machine) end end class ApiClient include Vagrant::Util::Retryable def initialize(machine) @logger = Log4r::Logger.new('vagrant::digitalocean::apiclient') @config = machine.provider_config @client = Faraday.new({ :url => 'https://api.digitalocean.com/', :ssl => { :ca_file => @config.ca_path } }) end def delete(path, params = {}, method = :delete) @client.request :url_encoded request(path, params, :delete) end def post(path, params = {}, method = :post) @client.headers['Content-Type'] = 'application/json' request(path, params, :post) end def request(path, params = {}, method = :get) begin @logger.info "Request: #{path}" result = @client.send(method) do |req| req.url path, params req.headers['Authorization'] = "Bearer #{@config.token}" end rescue Faraday::Error::ConnectionFailed => e # TODO this is suspect but because farady wraps the exception # in something generic there doesn't appear to be another # way to distinguish different connection errors :( if e.message =~ /certificate verify failed/ raise Errors::CertificateError end raise e end unless method == :delete begin body = JSON.parse(result.body) @logger.info "Response: #{body}" next_page = body["links"]["pages"]["next"] rescue nil unless next_page.nil? uri = URI.parse(next_page) new_path = path.split("?")[0] next_result = self.request("#{new_path}?#{uri.query}") req_target = new_path.split("/")[-1] body["#{req_target}"].concat(next_result["#{req_target}"]) end rescue JSON::ParserError => e raise(Errors::JSONError, { :message => e.message, :path => path, :params => params, :response => result.body }) end end unless /^2\d\d$/ =~ result.status.to_s raise(Errors::APIStatusError, { :path => path, :params => params, :status => result.status, :response => body.inspect }) end Result.new(body) end def wait_for_event(env, id) retryable(:tries => 120, :sleep => 10) do # stop waiting if interrupted next if env[:interrupted] # check action status result = self.request("/v2/actions/#{id}") yield result if block_given? raise 'not ready' if result['action']['status'] != 'completed' end end end end end end vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/helpers/result.rb000066400000000000000000000016721275450274700257650ustar00rootroot00000000000000module VagrantPlugins module DigitalOcean module Helpers class Result def initialize(body) @result = body end def [](key) @result[key.to_s] end def find_id(sub_obj, search) #:ssh_keys, {:name => 'ijin (vagrant)'} find(sub_obj, search)["id"] end def find(sub_obj, search) key = search.keys.first #:slug value = search[key].to_s #sfo1 key = key.to_s #slug result = @result[sub_obj.to_s].inject(nil) do |result, obj| obj[key] == value ? obj : result end result || error(sub_obj, key, value) end def error(sub_obj, key, value) raise(Errors::ResultMatchError, { :key => key, :value => value, :collection_name => sub_obj.to_s, :sub_obj => @result[sub_obj.to_s] }) end end end end end vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/plugin.rb000066400000000000000000000013571275450274700243030ustar00rootroot00000000000000module VagrantPlugins module DigitalOcean class Plugin < Vagrant.plugin('2') name 'DigitalOcean' description <<-DESC This plugin installs a provider that allows Vagrant to manage machines using DigitalOcean's API. DESC config(:digital_ocean, :provider) do require_relative 'config' Config end provider(:digital_ocean, parallel: true, defaultable: false) do require_relative 'provider' Provider end command(:rebuild) do require_relative 'commands/rebuild' Commands::Rebuild end command("digitalocean-list", primary: false) do require_relative 'commands/list' Commands::List end end end end vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/provider.rb000066400000000000000000000071141275450274700246340ustar00rootroot00000000000000require 'vagrant-digitalocean/actions' module VagrantPlugins module DigitalOcean class Provider < Vagrant.plugin('2', :provider) # This class method caches status for all droplets within # the DigitalOcean account. A specific droplet's status # may be refreshed by passing :refresh => true as an option. def self.droplet(machine, opts = {}) client = Helpers::ApiClient.new(machine) # load status of droplets if it has not been done before if !@droplets result = client.request('/v2/droplets') @droplets = result['droplets'] end if opts[:refresh] && machine.id # refresh the droplet status for the given machine @droplets.delete_if { |d| d['id'].to_s == machine.id } result = client.request("/v2/droplets/#{machine.id}") @droplets << droplet = result['droplet'] else # lookup droplet status for the given machine droplet = @droplets.find { |d| d['id'].to_s == machine.id } end # if lookup by id failed, check for a droplet with a matching name # and set the id to ensure vagrant stores locally # TODO allow the user to configure this behavior if !droplet name = machine.config.vm.hostname || machine.name droplet = @droplets.find { |d| d['name'] == name.to_s } machine.id = droplet['id'].to_s if droplet end droplet ||= {'status' => 'not_created'} end def initialize(machine) @machine = machine end def action(name) return Actions.send(name) if Actions.respond_to?(name) nil end # This method is called if the underying machine ID changes. Providers # can use this method to load in new data for the actual backing # machine or to realize that the machine is now gone (the ID can # become `nil`). No parameters are given, since the underlying machine # is simply the machine instance given to this object. And no # return value is necessary. def machine_id_changed end # This should return a hash of information that explains how to # SSH into the machine. If the machine is not at a point where # SSH is even possible, then `nil` should be returned. # # The general structure of this returned hash should be the # following: # # { # :host => "1.2.3.4", # :port => "22", # :username => "mitchellh", # :private_key_path => "/path/to/my/key" # } # # **Note:** Vagrant only supports private key based authenticatonion, # mainly for the reason that there is no easy way to exec into an # `ssh` prompt with a password, whereas we can pass a private key # via commandline. def ssh_info droplet = Provider.droplet(@machine) return nil if droplet['status'].to_sym != :active public_network = droplet['networks']['v4'].find { |network| network['type'] == 'public' } return { :host => public_network['ip_address'], :port => '22', :username => 'root', :private_key_path => nil } end # This should return the state of the machine within this provider. # The state must be an instance of {MachineState}. Please read the # documentation of that class for more information. def state state = Provider.droplet(@machine)['status'].to_sym long = short = state.to_s Vagrant::MachineState.new(state, short, long) end end end end vagrant-digitalocean-0.9.1/lib/vagrant-digitalocean/version.rb000066400000000000000000000001141275450274700244600ustar00rootroot00000000000000module VagrantPlugins module DigitalOcean VERSION = '0.9.1' end end vagrant-digitalocean-0.9.1/locales/000077500000000000000000000000001275450274700172435ustar00rootroot00000000000000vagrant-digitalocean-0.9.1/locales/en.yml000066400000000000000000000067021275450274700203750ustar00rootroot00000000000000en: vagrant_digital_ocean: info: off: "Droplet is off" not_created: "Droplet has not been created" already_active: "Droplet is already active" already_off: "Droplet is already off" creating: "Creating a new droplet..." droplet_ip: "Assigned IP address: %{ip}" droplet_private_ip: "Private IP address: %{ip}" destroying: "Destroying the droplet..." shutting_down: "Shutting down the droplet..." powering_off: "Powering off the droplet..." powering_on: "Powering on the droplet..." rebuilding: "Rebuilding the droplet..." reloading: "Rebooting the droplet..." creating_user: "Creating user account: %{user}..." late_sudo_install_deb8: "DigitalOcean's debian-8 image lacks sudo. Installing now." modifying_sudo: "Modifying sudoers file to remove tty requirement..." using_key: "Using existing SSH key: %{name}" creating_key: "Creating new SSH key: %{name}..." trying_rsync_install: "Rsync not found, attempting to install with yum..." rsyncing: "Rsyncing folder: %{hostpath} => %{guestpath}..." rsync_missing: "The rsync executable was not found in the current path." images: "Description Slug ID\n\n%{images}" images_with_regions: "Description Slug ID Regions\n\n%{images}" regions: "Description Slug\n\n%{regions}" sizes: "Memory CPUs Slug\n\n%{sizes}" list_error: 'Could not contact the DigitalOcean API: %{message}' config: token: "Token is required" private_key: "SSH private key path is required" public_key: "SSH public key not found: %{key}" errors: public_key: |- There was an issue reading the public key at: Path: %{path} Please check the file's permissions. api_status: |- There was an issue with the request made to the DigitalOcean API at: Path: %{path} URI Params: %{params} The response status from the API was: Status: %{status} Response: %{response} rsync: |- There was an error when attemping to rsync a share folder. Please inspect the error message below for more info. Host path: %{hostpath} Guest path: %{guestpath} Error: %{stderr} json: |- There was an issue with the JSON response from the DigitalOcean API at: Path: %{path} URI Params: %{params} The response JSON from the API was: Response: %{response} result_match: |- The result collection for %{collection_name}: %{sub_obj} Contained no object with the value "%{value}" for the the key "%{key}". Please ensure that the configured value exists in the collection. certificate: |- The secure connection to the DigitalOcean API has failed. Please ensure that your local certificates directory is defined in the provider config. config.vm.provider :digital_ocean do |vm| vm.ca_path = "/path/to/ssl/ca/cert.crt" end This is generally caused by the OpenSSL configuration associated with the Ruby install being unaware of the system specific ca certs. local_ip: |- The DigitalOcean provider was unable to determine the host's IP. vagrant-digitalocean-0.9.1/test/000077500000000000000000000000001275450274700166005ustar00rootroot00000000000000vagrant-digitalocean-0.9.1/test/Vagrantfile000066400000000000000000000020621275450274700207650ustar00rootroot00000000000000Vagrant.require_plugin('vagrant-digitalocean') Vagrant.require_plugin('vagrant-omnibus') Vagrant.configure('2') do |config| config.omnibus.chef_version = :latest config.ssh.username = 'tester' config.ssh.private_key_path = 'test_id_rsa' config.vm.synced_folder '.', '/vagrant', :disabled => true config.vm.provider :digital_ocean do |provider, override| override.vm.box = 'digital_ocean' override.vm.box_url = "https://github.com/smdahlen/vagrant-digitalocean/raw/master/box/digital_ocean.box" provider.token = ENV['DO_TOKEN'] provider.ssh_key_name = 'Test Key' end config.vm.provision :shell, :path => 'scripts/provision.sh' config.vm.provision :chef_solo do |chef| chef.cookbooks_path = 'cookbooks' chef.add_recipe 'test' end config.vm.define :ubuntu do |ubuntu| ubuntu.vm.provider :digital_ocean do |provider| provider.image = 'ubuntu-14-04-x64' end end config.vm.define :centos do |centos| centos.vm.provider :digital_ocean do |provider| provider.image = 'centos-6-5-x64' end end end vagrant-digitalocean-0.9.1/test/cookbooks/000077500000000000000000000000001275450274700205715ustar00rootroot00000000000000vagrant-digitalocean-0.9.1/test/cookbooks/test/000077500000000000000000000000001275450274700215505ustar00rootroot00000000000000vagrant-digitalocean-0.9.1/test/cookbooks/test/recipes/000077500000000000000000000000001275450274700232025ustar00rootroot00000000000000vagrant-digitalocean-0.9.1/test/cookbooks/test/recipes/default.rb000066400000000000000000000000251275450274700251500ustar00rootroot00000000000000log 'Testing 1 2 3!' vagrant-digitalocean-0.9.1/test/scripts/000077500000000000000000000000001275450274700202675ustar00rootroot00000000000000vagrant-digitalocean-0.9.1/test/scripts/provision.sh000066400000000000000000000000431275450274700226500ustar00rootroot00000000000000#!/bin/bash echo 'Testing 1 2 3!' vagrant-digitalocean-0.9.1/test/test.sh000077500000000000000000000005351275450274700201210ustar00rootroot00000000000000# if ! bundle exec vagrant box list | grep digital_ocean 1>/dev/null; then # bundle exec vagrant box add digital_ocean box/digital_ocean.box # fi cd test bundle exec vagrant up --provider=digital_ocean bundle exec vagrant up bundle exec vagrant provision bundle exec vagrant rebuild bundle exec vagrant halt bundle exec vagrant destroy cd .. vagrant-digitalocean-0.9.1/test/test_id_rsa000066400000000000000000000032131275450274700210220ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAmxZRyfvgXFxlPW9ivoxffdK9erqpCp1oitghUtDxbzPSCbNw qBoiJcnPVA/TuCxMnruUcNEXYgKfTL8lD3A1Hom8N1pTAhSed5m4qAGqTMubT15s cSR+SnDdriShErB/9YSb9LVn1aR0MsFS3H/+x1j4w5d6hBas8BhDfuVd16shvoaA OKy0ywy+NBuvGy/6Au3q3t7M9wdelODRnYLSWWqaLeYExRKxWWc7ape+oduQoe4r BNVwGmIOjWOM9aFPEPVHdLGO+LQyPExdeuS0rW96a39U4p8GjGzsrkNcKzVOGjM3 pIsGs3qOi7RzJ3z48HiBj9NT8I2fFpGHERerbQIDAQABAoIBABXsIcObhyuHJAh7 JkopLZZro70lhZ+qgIyf4JYEUxyVBqu4YcRhbVJKJLSNSDBQksQdX+5SoCuKk1oV 6vcztU6Lyb9JVVKF96CQajnVgm04msutXUbhEbkUG0Hyi5JIwM3D4QfGXNcmWAaU rVHeBfXH7eI4F2l0ix2lUGUvpwRFRDq9HgpOjXzyc57B4jeF7na/UTnt+Uoi4hzZ FjjQ7nSLqEJLXtQBqt4EnAZu6/9JlAApunyMOX2oTqRNn8XGmD0Rc+AouipHM+Mc 9/fN9oqVxxXw2MdJA6S/sEFLEDrbifmyyHOereuZtOjdWLqsCdZwewYl8nuBnYEU GjVzYgECgYEAx+efis7xma28HWqtW9GLvjBcFAD/f+MDDeqX9TKFwf+91tUq0QZi SqXvmIvCnpsO8I70WEskT+pPwJWReAbZBrCbCVDbH34KEkAHywH9sK6chWnB8OpU 0mp0gH89A4bq/tedKVHCQ2sAbKgbIc1zf3zpmMQiV+smMDQXU1fTg/kCgYEAxpst BD2cYftFjxFZE1v8fx6t6oHtzYRtNNFTYzfxzzRBaTTRRzdhSfh0tLFueyg/fcKR oCXUxbfCYRLk+zHP2p/AyyN9R5p2AMAc6lOZPpBj7u9kjjDVnk76DYnLDqP3Da2s i7b0DNYxm2gt1VSZfOuJHv7z85SLcJQsg+3ymBUCgYBrOpFX0d3Cw3COjvRitiox YJtjl411uf2fb2EHg4xAHcBlBn8rFDOROyUkPIOutBn1a5kh61yVCWiyMwiOy42K ixz+iEKhx+f7FiGYAX9lUKRg4/PGGMxa+gN4EchWpf5TqLCCw3pi03is0BeNsDjt /8EF0t9hLZ+UZ7zDVe79cQKBgGTPi5AlfeW2V96BHcfX31jfR8RLY1v4pj4zKrKo SRO2IKW4a6pMkBOuC/9UORJGocPCKY0y5sfduMrxfk2LQUhl4sS6JPNdkhxbZ9IB 0T2SqUc1OMN8QlJzIDYTBYFO9S56Q6U/nq2NY+zQesNYh/iCzj1viIDRm93vOJFX DNbpAoGBALlQvzzMsT3/fPYn8moQiUCJ9XRZ4X2qwYy5Q8J8QvutI+j9o9+pJBhc 3zSlB8HHa7asf27GUbYtv7oFDpqqcC6EFtvfp1OCiX/OjBIJA1YXTFG3YWC5ngC4 JPxyTn4MdoX0enm8PRDg7CSZwa4AK1MIYetbiuJgWJ2wKXDFxuGH -----END RSA PRIVATE KEY----- vagrant-digitalocean-0.9.1/test/test_id_rsa.pub000066400000000000000000000006351275450274700216140ustar00rootroot00000000000000ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCbFlHJ++BcXGU9b2K+jF990r16uqkKnWiK2CFS0PFvM9IJs3CoGiIlyc9UD9O4LEyeu5Rw0RdiAp9MvyUPcDUeibw3WlMCFJ53mbioAapMy5tPXmxxJH5KcN2uJKESsH/1hJv0tWfVpHQywVLcf/7HWPjDl3qEFqzwGEN+5V3XqyG+hoA4rLTLDL40G68bL/oC7ere3sz3B16U4NGdgtJZapot5gTFErFZZztql76h25Ch7isE1XAaYg6NY4z1oU8Q9Ud0sY74tDI8TF165LStb3prf1TinwaMbOyuQ1wrNU4aMzekiwazeo6LtHMnfPjweIGP01PwjZ8WkYcRF6tt digital_ocean provider test key vagrant-digitalocean-0.9.1/vagrant-digitalocean.gemspec000066400000000000000000000014221275450274700232500ustar00rootroot00000000000000# -*- encoding: utf-8 -*- lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'vagrant-digitalocean/version' Gem::Specification.new do |gem| gem.name = "vagrant-digitalocean" gem.version = VagrantPlugins::DigitalOcean::VERSION gem.authors = ["John Bender","Seth Reeser"] gem.email = ["john.m.bender@gmail.com","info@devopsgroup.io"] gem.description = %q{Enables Vagrant to manage DigitalOcean droplets} gem.summary = gem.description gem.files = `git ls-files`.split($/) gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) gem.require_paths = ["lib"] gem.add_dependency "faraday", ">= 0.8.6" gem.add_dependency "json" gem.add_dependency "log4r" end