Skip to content

Commit

Permalink
full refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
danryan committed Jun 13, 2012
1 parent f6ab41c commit 02b95ab
Show file tree
Hide file tree
Showing 17 changed files with 81 additions and 171 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -7,3 +7,5 @@ doc/**/*
.yardoc/*
Gemfile.lock
fixture.rb
coverage
wiki
1 change: 1 addition & 0 deletions Rakefile
Expand Up @@ -23,6 +23,7 @@ Bundler.require(:doc)
desc "Generate documentation"
YARD::Rake::YardocTask.new do |t|
t.files = [ 'lib/**/*.rb' ]
# t.options = [ "-M redcarpet" ]
end

desc "Generate docs"
Expand Down
3 changes: 2 additions & 1 deletion TODO.md
@@ -1,2 +1,3 @@
* Refactor classes that inherit from Spice::Chef to take config values
* Add support for data bag item creation
* Add support for data bag item creation
* implement GET /cookbooks?num_versions=all
32 changes: 27 additions & 5 deletions lib/spice.rb
Expand Up @@ -3,8 +3,6 @@
require 'spice/config'
require 'spice/connection'

require 'spice/mock'

module Spice
extend Spice::Config

Expand All @@ -27,8 +25,32 @@ def respond_to?(method, include_private=false)
end # def respond_to?

def mock
Spice::Mock.setup_mock_client
Spice.server_url = 'http://localhost:4000'
Spice.client_name = "testclient"
Spice.client_key = Spice.read_key_file(File.expand_path("../../spec/fixtures/client.pem", __FILE__))
Spice.chef_version = "0.10.10"
self
end # def mock
end
end

def read_key_file(key_file_path)

begin
raw_key = File.read(key_file_path).strip
rescue SystemCallError, IOError => e
raise IOError, "Unable to read #{key_file_path}"
end

begin_rsa = "-----BEGIN RSA PRIVATE KEY-----"
end_rsa = "-----END RSA PRIVATE KEY-----"

unless (raw_key =~ /\A#{begin_rsa}$/) && (raw_key =~ /^#{end_rsa}\Z/)
msg = "The file #{key_file} is not a properly formatted private key.\n"
msg << "It must contain '#{begin_rsa}' and '#{end_rsa}'"
raise ArgumentError, msg
end
return OpenSSL::PKey::RSA.new(raw_key)
end # def read_key_file

end # class << self
end # module Spice

23 changes: 4 additions & 19 deletions lib/spice/authentication.rb
Expand Up @@ -6,37 +6,22 @@ module Spice
module Authentication

def signature_headers(method, path, json_body=nil)
uri = URI(Spice.server_url)
uri = URI(server_url)

params = {
:http_method => method,
:path => path,
:body => json_body || "",
:host => "#{uri.host}:#{uri.port}",
:timestamp => Time.now.utc.iso8601,
:user_id => Spice.client_name
:user_id => client_name
}

begin
raw_key = File.read(Spice.key_file).strip
rescue SystemCallError, IOError => e
raise IOError, "Unable to read #{key_file}"
end

unless (raw_key =~ /\A-----BEGIN RSA PRIVATE KEY-----$/) &&
(raw_key =~ /^-----END RSA PRIVATE KEY-----\Z/)
msg = "The file #{key_file} is not a properly formatted private key.\n"
msg << "It must contain '-----BEGIN RSA PRIVATE KEY-----' and '-----END RSA PRIVATE KEY-----'"
raise ArgumentError, msg
end

key = OpenSSL::PKey::RSA.new(raw_key)

signing_object = Mixlib::Authentication::SignedHeaderAuth.signing_object(params)
signed_headers = signing_object.sign(key)
signed_headers = signing_object.sign(client_key)

# Platform requires X-Chef-Version header
signed_headers['X-Chef-Version'] = Spice.chef_version
signed_headers['X-Chef-Version'] = chef_version
# signed_headers['Content-Length'] = json_body.bytesize.to_s if json_body
signed_headers
end # def signature_headers
Expand Down
14 changes: 7 additions & 7 deletions lib/spice/config.rb
Expand Up @@ -19,16 +19,17 @@ module Config
DEFAULT_CONNECTION_OPTIONS = {}

# Default client name
DEFAULT_CLIENT_NAME = nil
DEFAULT_CLIENT_NAME = ""

# Default key file
DEFAULT_KEY_FILE = nil
DEFAULT_CLIENT_KEY = ""

# An array of valid config options

VALID_OPTIONS_KEYS = [
:server_url,
:client_name,
:key_file,
:client_key,
:chef_version,
:user_agent,
:connection_options,
Expand Down Expand Up @@ -56,11 +57,10 @@ def self.extended(base)
# Spice.setup do |s|
# s.server_url = "http://chef.example.com:4000"
# s.client_name = "admin"
# s.key_file = "/home/admin/.chef/admin.pem"
# s.client_key = Spice.read_key_file("/path/to/key_file.pem")
# end
# @yieldparam Spice
# @yieldreturn Spice

# @yieldreturn Spice
def setup
yield self
self
Expand All @@ -79,7 +79,7 @@ def reset
self.server_url = DEFAULT_SERVER_URL
self.chef_version = DEFAULT_CHEF_VERSION
self.client_name = DEFAULT_CLIENT_NAME
self.key_file = DEFAULT_KEY_FILE
self.client_key = DEFAULT_CLIENT_KEY
self.connection_options = DEFAULT_CONNECTION_OPTIONS
self.middleware = DEFAULT_MIDDLEWARE
self
Expand Down
8 changes: 6 additions & 2 deletions lib/spice/connection.rb
Expand Up @@ -33,8 +33,12 @@ class Connection
include Spice::Connection::Search
include Spice::Request
include Spice::Authentication

attr_accessor *Config::VALID_OPTIONS_KEYS

# @private

Config::VALID_OPTIONS_KEYS.each do |key|
attr_accessor key
end

def initialize(attrs=Mash.new)
attrs = Spice.options.merge(attrs)
Expand Down
6 changes: 3 additions & 3 deletions lib/spice/connection/cookbooks.rb
Expand Up @@ -8,15 +8,15 @@ module Cookbooks
def cookbooks
if Gem::Version.new(Spice.chef_version) >= Gem::Version.new("0.10.0")
cookbooks = []
get("/cookbooks").each_pair do |key, value|
get("/cookbooks?num_versions=all").each_pair do |key, value|
versions = value['versions'].map{ |v| v['version'] }
cookbooks << Spice::Cookbook.get_or_new(:name => key, :versions => versions)
end
cookbooks
else
get("/cookbooks").keys.map do |cookbook|
attributes = get("/cookbooks/#{cookbook}").to_a[0]
Spice::Cookbook.get_or_new(:name => attributes[0], :versions => attributes[1])
cb = get("/cookbooks/#{cookbook}")
Spice::Cookbook.get_or_new(:name => cookbook, :versions => cb[cookbook])
end
end
end # def cookbooks
Expand Down
5 changes: 2 additions & 3 deletions lib/spice/connection/data_bags.rb
Expand Up @@ -29,9 +29,8 @@ def data_bag(name)
# @return [Spice::DataBagItem]
# @raise [Spice::Error::NotFound] raised when data bag item does not exist
def data_bag_item(name, id)
data = get("/data/#{name}/#{id}")
data.delete('id')
Spice::DataBagItem.get_or_new(:_id => id, :data => data, :name => name)
data_bag_item = get("/data/#{name}/#{id}")
Spice::DataBagItem.get_or_new(data_bag_item)
end # def data_bag_item

def create_data_bag(name)
Expand Down
1 change: 1 addition & 0 deletions lib/spice/connection/search.rb
Expand Up @@ -8,6 +8,7 @@ module Search
# @option options [Numeric] :start The number by which to offset the results
# @option options [Numeric] :rows The maximum number of rows to return
def search(index, options=Mash.new)
index = index.to_s
options = {:q => options} if options.is_a? String
options.symbolize_keys!

Expand Down
14 changes: 4 additions & 10 deletions lib/spice/core_ext/mash.rb
Expand Up @@ -53,7 +53,7 @@ class Mash < Hash
# @param constructor<Object>
# The default value for the mash. Defaults to an empty hash.
#
# @details [Alternatives]
# [Alternatives]
# If constructor is a Hash, a new mash will be created based on the keys of
# the hash and no default value will be set.
def initialize(constructor = {})
Expand Down Expand Up @@ -81,7 +81,7 @@ def initialize_copy(orig)

# @param key<Object> The default value for the mash. Defaults to nil.
#
# @details [Alternatives]
# [Alternatives]
# If key is a Symbol and it is a key in the mash, then the default value will
# be set to the value matching the key.
def default(key = nil)
Expand Down Expand Up @@ -130,14 +130,14 @@ def key?(key)
alias_method :member?, :key?

# @param key<Object> The key to fetch. This will be run through convert_key.
# @param *extras<Array> Default value.
# @param extras<Array> Default value.
#
# @return [Object] The value at key or the default value.
def fetch(key, *extras)
super(convert_key(key), *extras)
end

# @param *indices<Array>
# @param indices<Array>
# The keys to retrieve values for. These will be run through +convert_key+.
#
# @return [Array] The values at each of the provided keys
Expand All @@ -158,8 +158,6 @@ def delete(key)
super(convert_key(key))
end

# @param *rejected<Array[(String, Symbol)] The mash keys to exclude.
#
# @return [Mash] A new mash without the selected keys.
#
# @example
Expand Down Expand Up @@ -197,10 +195,6 @@ def self.from_hash(hash)
protected
# @param key<Object> The key to convert.
#
# @param [Object]
# The converted key. If the key was a symbol, it will be converted to a
# string.
#
# @api private
def convert_key(key)
key.kind_of?(Symbol) ? key.to_s : key
Expand Down
12 changes: 6 additions & 6 deletions lib/spice/environment.rb
Expand Up @@ -5,13 +5,13 @@ class Environment < Base
attr_reader :name, :description, :attributes, :cookbook_versions,
:chef_type, :json_class

def json_class
@json_class ||= "Chef::Environment"
def initialize(attrs=Mash.new)
super
@attrs['json_class'] ||= "Chef::Environment"
@attrs['chef_type'] ||= "environment"
@attrs['attributes'] ||= Mash.new
@attrs['cookbook_version'] ||= Mash.new
end

def chef_type
@chef_type ||= 'environment'
end

end
end
45 changes: 0 additions & 45 deletions lib/spice/mock.rb

This file was deleted.

62 changes: 0 additions & 62 deletions lib/spice/persistence.rb

This file was deleted.

0 comments on commit 02b95ab

Please sign in to comment.