Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Digital Ocean support! #55

Merged
merged 1 commit into from
Sep 15, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 54 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
[![Code Climate](https://codeclimate.com/github/fnichol/knife-server.png)](https://codeclimate.com/github/fnichol/knife-server)
[![Dependency Status](https://gemnasium.com/fnichol/knife-server.png)](https://gemnasium.com/fnichol/knife-server)

An Opscode Chef knife plugin to manage Chef Servers. Bootstrap a new Chef
Server on Amazon's EC2, Linode or a standalone server. Backup and restore
your Chef Server or Hosted Chef's node, role, data bag, and environment JSON
data.
An Chef Knife plugin to manage Chef Servers. Bootstrap a new Chef
Server on Amazon's EC2, Digital Ocean, Linode, OpenStack or a standalone server.
Backup and restore your Chef Server or Hosted Chef's node, role, data bag, and
environment JSON data.

## <a name="usage"></a> Usage

Expand Down Expand Up @@ -39,6 +39,20 @@ $ knife server bootstrap ec2 \
--ssh-user ubuntu
```

To spin up your Chef Server on [Digital Ocean][do_site]:

```bash
knife server bootstrap digitalocean \
--node-name chefapalooza.example.com \
--digital_ocean_client_id $DIGITAL_OCEAN_CLIENT_ID \
--digital_ocean_api_key $DIGITAL_OCEAN_API_KEY \
--location 3 \
--size 63 \
--image 5588928 \
--ssh-keys $DIGITAL_OCEAN_SSH_KEY_ID \
--identity-file ~/.ssh/id_rsa-do
```

To spin up your Chef Server on Linode:

```bash
Expand Down Expand Up @@ -122,12 +136,15 @@ Add this line to your application's Gemfile:
gem 'knife-server'
```

**Note** If you want to use the `bootstrap ec2` or `bootstrap linode`
**Note** If you want to use the `bootstrap ec2`, `bootstrap digitalocean`,
`bootstrap linode`, or `bootstrap openstack`
subcommands you will need to explicitly add this to your Gemfile with:

```ruby
gem 'knife-ec2'
gem 'knife-digital_ocean'
gem 'knife-linode'
gem 'knife-openstack'
```

Finally execute:
Expand All @@ -142,8 +159,9 @@ Or install it yourself as:
$ gem install knife-server
```

(Don't forget a `gem install knife-ec2` or `gem install knife-linode` if using
the `bootstrap ec2` or `bootstrap linode` subcommands).
(Don't forget a `gem install knife-ec2`, `gem install knife-digital_ocean`,
`gem install knife-linode`, or `gem install knife-openstack` if using any
cloud-specific subcommands).

Next, you **must** set up a [knife.rb configuration](#installation-knife) so
that the shipped Knife subcommands know where to place and modify key files,
Expand Down Expand Up @@ -196,6 +214,10 @@ knife[:flavor] = "t1.micro"

# for linode
knife[:linode_api_key] = "MY_KEY"

# for digitalocean
knife[:digital_ocean_client_id] = "MY_CLIENT_ID"
knife[:digital_ocean_api_key] = "MY_KEY"
```

Better yet, why not try a more generic [knife.rb][chef_bootstrap_knife_rb] file
Expand Down Expand Up @@ -408,22 +430,28 @@ The resulting set will include:
* `"Node=#{config[:chef_node_name]}"`
* `"Role=chef_server"`

### <a name="knife-server-bootstrap-linode"></a> knife server bootstrap linode
### <a name="knife-server-bootstrap-digitalocean"></a> knife server bootstrap digitalocean

**Note:** You must install the [knife-linode gem][knife-linode] to use this
subcommand. This was done to keep the dependencies of this library lighter and
to make future cloud adapter support easier to add.
**Note:** You must install the [knife-digital_ocean gem][knife-digital_ocean]
to use this subcommand. This was done to keep the dependencies of this library
lighter and to make future cloud adapter support easier to add.

Provisions a Linode instance and sets up an Open Source Chef Server as
Provisions a Digital Ocean droplet and sets up an Open Source Chef Server as
described [above](#knife-server-bootstrap).

### <a name="knife-server-bootstrap-openstack"></a> knife server bootstrap openstack
#### Configuration

**Note:** You must install the [knife-openstack gem][knife-openstack] to use this
This subcommand imports all relavent options from the knife-digital_ocean gem.
For detailed documentation relating to these options, please visit the [project
page][knife-digital_ocean].

### <a name="knife-server-bootstrap-linode"></a> knife server bootstrap linode

**Note:** You must install the [knife-linode gem][knife-linode] to use this
subcommand. This was done to keep the dependencies of this library lighter and
to make future cloud adapter support easier to add.

Provisions a Openstack instance and sets up an Open Source Chef Server as
Provisions a Linode instance and sets up an Open Source Chef Server as
described [above](#knife-server-bootstrap).

#### Configuration
Expand Down Expand Up @@ -480,6 +508,15 @@ password so that you know how to connect later.

The default value is a random password.

### <a name="knife-server-bootstrap-openstack"></a> knife server bootstrap openstack

**Note:** You must install the [knife-openstack gem][knife-openstack] to use this
subcommand. This was done to keep the dependencies of this library lighter and
to make future cloud adapter support easier to add.

Provisions a Openstack instance and sets up an Open Source Chef Server as
described [above](#knife-server-bootstrap).

### <a name="knife-server-bootstrap-standalone"></a> knife server bootstrap standalone

Provisions a standalone server that is reachable on the network and sets up
Expand Down Expand Up @@ -638,11 +675,13 @@ Apache License, Version 2.0 (see [LICENSE][license])
[backup_restore]: https://github.com/stevendanna/knife-hacks/blob/master/plugins/backup_restore.rb
[chef_bootstrap_knife_rb]: https://github.com/fnichol/chef-bootstrap-repo/blob/master/.chef/knife.rb
[chef_bootstrap_repo]: https://github.com/fnichol/chef-bootstrap-repo/
[do_site]: https://www.digitalocean.com/
[docs_knife]: http://docs.opscode.com/config_rb_knife.html
[docs_knife_ec2]: http://docs.opscode.com/plugin_knife_ec2.html
[docs_knife_linode]: http://docs.opscode.com/plugin_knife_linode.html
[jtimberman]: https://github.com/jtimberman
[install_chef]: http://www.opscode.com/chef/install/
[knife-digital_ocean]: https://github.com/rmoriz/knife-digital_ocean
[knife-ec2]: https://github.com/opscode/knife-ec2
[knife-linode]: https://github.com/opscode/knife-linode
[knife-openstack]: https://github.com/opscode/knife-openstack
Expand Down
1 change: 1 addition & 0 deletions knife-server.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Gem::Specification.new do |gem|
gem.add_dependency "chef", ">= 0.10.10"

gem.add_development_dependency "rake"
gem.add_development_dependency "knife-digital_ocean"
gem.add_development_dependency "knife-ec2", ">= 0.5.12"
gem.add_development_dependency "knife-linode"
gem.add_development_dependency "knife-openstack"
Expand Down
153 changes: 153 additions & 0 deletions lib/chef/knife/server_bootstrap_digitalocean.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# -*- encoding: utf-8 -*-
#
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
# Copyright:: Copyright (c) 2014 Fletcher Nichol
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

require "chef/knife/server_bootstrap_base"

class Chef
class Knife
# Provisions a Digital Ocean instance and sets up an Open Source Chef
# Server.
class ServerBootstrapDigitalocean < Knife

banner "knife server bootstrap digitalocean (options)"

include Knife::ServerBootstrapBase

deps do
require "knife/server/ssh"
require "knife/server/credentials"

begin
require "chef/knife/digital_ocean_droplet_create"
require "fog"
Chef::Knife::DigitalOceanDropletCreate.load_deps

current_options = options
self.options = Chef::Knife::DigitalOceanDropletCreate.options.dup
options.merge!(current_options)
rescue LoadError => ex
ui.error [
"Knife plugin knife-digital_ocean could not be loaded.",
"Please add the knife-digital_ocean gem to your Gemfile or",
"install the gem manually with `gem install knife-digital_ocean'.",
"(#{ex.message})"
].join(" ")
exit 1
end

# Monkey patch to prevent Kernel#exit calls at the end of the upstream
# Knife plugin. Instead, non-zero exits will be raised and zero exits
# will be ignored ;)
#
# rubocop:disable Style/ClassAndModuleChildren
class ::Chef::Knife::DigitalOceanDropletCreate
def exit(code)
if code != 0
raise "DigitalOceanDropletCreate exited with code: #{code}"
end
end
end
# rubocop:enable Style/ClassAndModuleChildren
end

option :chef_node_name,
:short => "-N NAME",
:long => "--node-name NAME",
:description => "The Chef node name for your new node",
:proc => proc { |key| Chef::Config[:knife][:server_name] = key }

def run
super
digital_ocean_bootstrap.run
fetch_validation_key
create_root_client
install_client_key
end

def digital_ocean_bootstrap
setup_environment
bootstrap = Chef::Knife::DigitalOceanDropletCreate.new
bootstrap.config[:bootstrap] = true
Chef::Knife::DigitalOceanDropletCreate.options.keys.each do |attr|
val = config_val(attr)
next if val.nil?

bootstrap.config[attr] = val
end
bootstrap.config[:server_name] = config_val(:chef_node_name)
bootstrap.config[:distro] = bootstrap_distro
bootstrap
end

def digital_ocean_connection
@digital_ocean_connection ||= Fog::Compute.new(
:provider => "DigitalOcean",
:digitalocean_client_id => config_val(:digital_ocean_client_id),
:digitalocean_api_key => config_val(:digital_ocean_api_key)
)
end

def server_ip_address
server = digital_ocean_connection.servers.find do |s|
s.state == "active" && s.name == config_val(:chef_node_name)
end

server && server.public_ip_address
end

private

def validate!
super

if config[:chef_node_name].nil?
ui.error "You did not provide a valid --node-name value."
exit 1
end
if config_val(:platform) == "auto"
ui.error "Auto platform mode cannot be used with " \
"knife-digital_ocean plugin"
exit 1
end
end

def setup_environment
ENV["WEBUI_PASSWORD"] = config_val(:webui_password)
ENV["AMQP_PASSWORD"] = config_val(:amqp_password)
ENV["NO_TEST"] = "1" if config[:no_test]
end

def ssh_connection
opts = {
:host => server_ip_address,
:user => config_val(:ssh_user),
:port => "22",
:keys => [config_val(:identity_file)].compact,
:password => config_val(:ssh_password)
}
if config_val(:host_key_verify) == false
opts[:user_known_hosts_file] = "/dev/null"
opts[:paranoid] = false
end

::Knife::Server::SSH.new(opts)
end
end
end
end
Loading