bosh_openstack_registry 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,3 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ BOSH OpenStack Registry
data/Rakefile ADDED
@@ -0,0 +1,50 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ $:.unshift(File.expand_path("../../rake", __FILE__))
4
+
5
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __FILE__)
6
+
7
+ require "rubygems"
8
+ require "bundler"
9
+ Bundler.setup(:default, :test)
10
+
11
+ require "rake"
12
+ begin
13
+ require "rspec/core/rake_task"
14
+ rescue LoadError
15
+ end
16
+
17
+ require "bundler_task"
18
+ require "ci_task"
19
+
20
+ gem_helper = Bundler::GemHelper.new(Dir.pwd)
21
+
22
+ desc "Build OpenStack Registry gem into the pkg directory"
23
+ task "build" do
24
+ gem_helper.build_gem
25
+ end
26
+
27
+ desc "Build and install OpenStack Registry into system gems"
28
+ task "install" do
29
+ Rake::Task["bundler:install"].invoke
30
+ gem_helper.install_gem
31
+ end
32
+
33
+ BundlerTask.new
34
+
35
+ if defined?(RSpec)
36
+ namespace :spec do
37
+ desc "Run Unit Tests"
38
+ rspec_task = RSpec::Core::RakeTask.new(:unit) do |t|
39
+ t.pattern = "spec/unit/**/*_spec.rb"
40
+ t.rspec_opts = %w(--format progress --colour)
41
+ end
42
+
43
+ CiTask.new do |task|
44
+ task.rspec_task = rspec_task
45
+ end
46
+ end
47
+
48
+ desc "Run tests"
49
+ task :spec => %w(spec:unit)
50
+ end
data/bin/migrate ADDED
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ENV["BUNDLE_GEMFILE"] = File.expand_path("../../Gemfile", __FILE__)
4
+
5
+ require "rubygems"
6
+ require "bundler/setup"
7
+ require "logger"
8
+ require "sequel"
9
+
10
+ $:.unshift(File.dirname(__FILE__) + "/../lib")
11
+
12
+ require "openstack_registry"
13
+
14
+ config_file = nil
15
+
16
+ opts = OptionParser.new do |opts|
17
+ opts.on("-c", "--config FILE", "configuration file") do |opt|
18
+ config_file = opt
19
+ end
20
+ end
21
+
22
+ opts.parse!(ARGV.dup)
23
+
24
+ if config_file.nil?
25
+ puts opts
26
+ exit 1
27
+ end
28
+
29
+ include Bosh::OpenstackRegistry::YamlHelper
30
+
31
+ config = load_yaml_file(config_file)
32
+
33
+ db = Bosh::OpenstackRegistry.connect_db(config["db"])
34
+ migrations_dir = File.expand_path("../../db/migrations", __FILE__)
35
+
36
+ options = {
37
+ :table => "openstack_registry_schema"
38
+ }
39
+
40
+ Sequel.extension :migration
41
+ Sequel::TimestampMigrator.run(db, migrations_dir, options)
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ gemfile = File.expand_path("../../Gemfile", __FILE__)
4
+
5
+ if File.exists?(gemfile)
6
+ ENV["BUNDLE_GEMFILE"] = gemfile
7
+ require "rubygems"
8
+ require "bundler/setup"
9
+ end
10
+
11
+ $:.unshift(File.expand_path("../../lib", __FILE__))
12
+
13
+ require "openstack_registry"
14
+ require "optparse"
15
+
16
+ config_file = nil
17
+
18
+ opts = OptionParser.new do |opts|
19
+ opts.on("-c", "--config FILE", "configuration file") do |opt|
20
+ config_file = opt
21
+ end
22
+ end
23
+
24
+ opts.parse!(ARGV.dup)
25
+
26
+ if config_file.nil?
27
+ puts opts
28
+ exit 1
29
+ end
30
+
31
+ runner = Bosh::OpenstackRegistry::Runner.new(config_file)
32
+
33
+ Signal.trap("INT") do
34
+ runner.stop
35
+ exit(1)
36
+ end
37
+
38
+ runner.run
@@ -0,0 +1,67 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh::OpenstackRegistry
4
+
5
+ class ApiController < Sinatra::Base
6
+
7
+ not_found do
8
+ json(:status => "not_found")
9
+ end
10
+
11
+ error do
12
+ exception = request.env["sinatra.error"]
13
+ @logger.error(exception)
14
+ status(500)
15
+ json(:status => "error")
16
+ end
17
+
18
+ get "/servers/:server_id/settings" do
19
+ ip_check = authorized? ? nil : request.ip
20
+ settings = @server_manager.read_settings(params[:server_id])
21
+ json(:status => "ok", :settings => settings)
22
+ end
23
+
24
+ put "/servers/:server_id/settings" do
25
+ protected!
26
+ @server_manager.update_settings(params[:server_id], request.body.read)
27
+ json(:status => "ok")
28
+ end
29
+
30
+ delete "/servers/:server_id/settings" do
31
+ protected!
32
+ @server_manager.delete_settings(params[:server_id])
33
+ json(:status => "ok")
34
+ end
35
+
36
+ def initialize
37
+ super
38
+ @logger = Bosh::OpenstackRegistry.logger
39
+
40
+ @users = Set.new
41
+ @users << [Bosh::OpenstackRegistry.http_user,
42
+ Bosh::OpenstackRegistry.http_password]
43
+ @server_manager = ServerManager.new
44
+ end
45
+
46
+ def protected!
47
+ unless authorized?
48
+ headers("WWW-Authenticate" => 'Basic realm="OpenStack Registry"')
49
+ halt(401, json("status" => "access_denied"))
50
+ end
51
+ end
52
+
53
+ def authorized?
54
+ @auth ||= Rack::Auth::Basic::Request.new(request.env)
55
+ @auth.provided? &&
56
+ @auth.basic? &&
57
+ @auth.credentials &&
58
+ @users.include?(@auth.credentials)
59
+ end
60
+
61
+ def json(payload)
62
+ Yajl::Encoder.encode(payload)
63
+ end
64
+
65
+ end
66
+
67
+ end
@@ -0,0 +1,81 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh::OpenstackRegistry
4
+
5
+ class << self
6
+
7
+ attr_accessor :logger
8
+ attr_accessor :http_port
9
+ attr_accessor :http_user
10
+ attr_accessor :http_password
11
+ attr_accessor :db
12
+
13
+ attr_writer :openstack
14
+
15
+ def configure(config)
16
+ validate_config(config)
17
+
18
+ @logger ||= Logger.new(config["logfile"] || STDOUT)
19
+
20
+ if config["loglevel"].kind_of?(String)
21
+ @logger.level = Logger.const_get(config["loglevel"].upcase)
22
+ end
23
+
24
+ @http_port = config["http"]["port"]
25
+ @http_user = config["http"]["user"]
26
+ @http_password = config["http"]["password"]
27
+
28
+ @openstack_properties = config["openstack"]
29
+
30
+ @openstack_options = {
31
+ :provider => "OpenStack",
32
+ :openstack_auth_url => @openstack_properties["auth_url"],
33
+ :openstack_username => @openstack_properties["username"],
34
+ :openstack_api_key => @openstack_properties["api_key"],
35
+ :openstack_tenant => @openstack_properties["tenant"]
36
+ }
37
+
38
+ @db = connect_db(config["db"])
39
+ end
40
+
41
+ def openstack
42
+ openstack ||= Fog::Compute.new(@openstack_options)
43
+ end
44
+
45
+ def connect_db(db_config)
46
+ connection_options = {
47
+ :max_connections => db_config["max_connections"],
48
+ :pool_timeout => db_config["pool_timeout"]
49
+ }
50
+
51
+ db = Sequel.connect(db_config["database"], connection_options)
52
+ db.logger = @logger
53
+ db.sql_log_level = :debug
54
+ db
55
+ end
56
+
57
+ def validate_config(config)
58
+ unless config.is_a?(Hash)
59
+ raise ConfigError, "Invalid config format, Hash expected, " \
60
+ "#{config.class} given"
61
+ end
62
+
63
+ unless config.has_key?("http") && config["http"].is_a?(Hash)
64
+ raise ConfigError, "HTTP configuration is missing from " \
65
+ "config file"
66
+ end
67
+
68
+ unless config.has_key?("db") && config["db"].is_a?(Hash)
69
+ raise ConfigError, "Database configuration is missing from " \
70
+ "config file"
71
+ end
72
+
73
+ unless config.has_key?("openstack") && config["openstack"].is_a?(Hash)
74
+ raise ConfigError, "OpenStack configuration is missing from " \
75
+ "config file"
76
+ end
77
+ end
78
+
79
+ end
80
+
81
+ end
@@ -0,0 +1,20 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh::OpenstackRegistry
4
+
5
+ class Error < StandardError
6
+ def self.code(code = 500)
7
+ define_method(:code) { code }
8
+ end
9
+ end
10
+
11
+ class FatalError < Error; end
12
+
13
+ class ConfigError < Error; end
14
+ class ConnectionError < Error; end
15
+
16
+ class OpenstackError < Error; end
17
+
18
+ class ServerError < Error; end
19
+ class ServerNotFound < Error; code(404); end
20
+ end
@@ -0,0 +1,12 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh::OpenstackRegistry::Models
4
+ class OpenstackServer < Sequel::Model
5
+
6
+ def validate
7
+ validates_presence [:server_id, :settings]
8
+ validates_unique :server_id
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,8 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh::OpenstackRegistry
4
+ module Models
5
+ end
6
+ end
7
+
8
+ require "openstack_registry/models/openstack_server"
@@ -0,0 +1,56 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh::OpenstackRegistry
4
+ class Runner
5
+ include YamlHelper
6
+
7
+ def initialize(config_file)
8
+ Bosh::OpenstackRegistry.configure(load_yaml_file(config_file))
9
+
10
+ @logger = Bosh::OpenstackRegistry.logger
11
+ @http_port = Bosh::OpenstackRegistry.http_port
12
+ @http_user = Bosh::OpenstackRegistry.http_user
13
+ @http_password = Bosh::OpenstackRegistry.http_password
14
+ end
15
+
16
+ def run
17
+ @logger.info("BOSH OpenStack Registry starting...")
18
+ EM.kqueue if EM.kqueue?
19
+ EM.epoll if EM.epoll?
20
+
21
+ EM.error_handler { |e| handle_em_error(e) }
22
+
23
+ EM.run do
24
+ start_http_server
25
+ end
26
+ end
27
+
28
+ def stop
29
+ @logger.info("BOSH OpenStack Registry shutting down...")
30
+ @http_server.stop! if @http_server
31
+ EM.stop
32
+ end
33
+
34
+ def start_http_server
35
+ @logger.info "HTTP server is starting on port #{@http_port}..."
36
+ @http_server = Thin::Server.new("0.0.0.0", @http_port, :signals => false) do
37
+ Thin::Logging.silent = true
38
+ map "/" do
39
+ run Bosh::OpenstackRegistry::ApiController.new
40
+ end
41
+ end
42
+ @http_server.start!
43
+ end
44
+
45
+ private
46
+
47
+ def handle_em_error(e)
48
+ @logger.send(level, e.to_s)
49
+ if e.respond_to?(:backtrace) && e.backtrace.respond_to?(:join)
50
+ @logger.send(level, e.backtrace.join("\n"))
51
+ end
52
+ stop
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,52 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh::OpenstackRegistry
4
+
5
+ class ServerManager
6
+
7
+ def initialize
8
+ @logger = Bosh::OpenstackRegistry.logger
9
+ @openstack = Bosh::OpenstackRegistry.openstack
10
+ end
11
+
12
+ ##
13
+ # Updates server settings
14
+ # @param [String] server_id OpenStack server id (server record
15
+ # will be created in DB if it doesn't already exist)
16
+ # @param [String] settings New settings for the server
17
+ def update_settings(server_id, settings)
18
+ params = {
19
+ :server_id => server_id
20
+ }
21
+
22
+ server = Models::OpenstackServer[params] || Models::OpenstackServer.new(params)
23
+ server.settings = settings
24
+ server.save
25
+ end
26
+
27
+ ##
28
+ # Reads server settings
29
+ # @param [String] server_id OpenStack server id
30
+ def read_settings(server_id)
31
+ get_server(server_id).settings
32
+ end
33
+
34
+ def delete_settings(server_id)
35
+ get_server(server_id).destroy
36
+ end
37
+
38
+ private
39
+
40
+ def get_server(server_id)
41
+ server = Models::OpenstackServer[:server_id => server_id]
42
+
43
+ if server.nil?
44
+ raise ServerNotFound, "Can't find server `#{server_id}'"
45
+ end
46
+
47
+ server
48
+ end
49
+
50
+ end
51
+
52
+ end
@@ -0,0 +1,7 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh
4
+ module OpenstackRegistry
5
+ VERSION = "0.0.1"
6
+ end
7
+ end
@@ -0,0 +1,24 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh::OpenstackRegistry
4
+ module YamlHelper
5
+
6
+ def load_yaml_file(path, expected_type = Hash)
7
+ unless File.exists?(path)
8
+ raise(ConfigError, "Cannot find file `#{path}'")
9
+ end
10
+
11
+ yaml = YAML.load_file(path)
12
+
13
+ if expected_type && !yaml.is_a?(expected_type)
14
+ raise ConfigError, "Incorrect file format in `#{path}', " \
15
+ "#{expected_type} expected"
16
+ end
17
+
18
+ yaml
19
+ rescue SystemCallError => e
20
+ raise ConfigError, "Cannot load YAML file at `#{path}': #{e}"
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,25 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh
4
+ module OpenstackRegistry
5
+ autoload :Models, "openstack_registry/models"
6
+ end
7
+ end
8
+
9
+ require "fog"
10
+ require "logger"
11
+ require "sequel"
12
+ require "sinatra/base"
13
+ require "thin"
14
+ require "yajl"
15
+
16
+ require "openstack_registry/yaml_helper"
17
+
18
+ require "openstack_registry/api_controller"
19
+ require "openstack_registry/config"
20
+ require "openstack_registry/errors"
21
+ require "openstack_registry/server_manager"
22
+ require "openstack_registry/runner"
23
+ require "openstack_registry/version"
24
+
25
+ Sequel::Model.plugin :validation_helpers
@@ -0,0 +1,18 @@
1
+ ---
2
+ loglevel: debug
3
+
4
+ http:
5
+ port: 25695
6
+ user: admin
7
+ password: admin
8
+
9
+ db:
10
+ database: "sqlite:///:memory:"
11
+ max_connections: 32
12
+ pool_timeout: 10
13
+
14
+ openstack:
15
+ auth_url: "http://127.0.0.1:5000/v2.0/tokens"
16
+ username: foo
17
+ api_key: bar
18
+ tenant: foo
@@ -0,0 +1,114 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ $:.unshift(File.expand_path("../../lib", __FILE__))
4
+
5
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__)
6
+
7
+ require "rubygems"
8
+ require "bundler"
9
+ Bundler.setup(:default, :test)
10
+
11
+ require "fileutils"
12
+ require "logger"
13
+ require "tmpdir"
14
+
15
+ require "rspec"
16
+ require "rack/test"
17
+
18
+ module SpecHelper
19
+ class << self
20
+ attr_accessor :logger
21
+ attr_accessor :temp_dir
22
+
23
+ def init
24
+ ENV["RACK_ENV"] = "test"
25
+ configure_logging
26
+ configure_temp_dir
27
+
28
+ require "openstack_registry"
29
+ init_database
30
+ end
31
+
32
+ def configure_logging
33
+ if ENV["DEBUG"]
34
+ @logger = Logger.new(STDOUT)
35
+ else
36
+ path = File.expand_path("../spec.log", __FILE__)
37
+ log_file = File.open(path, "w")
38
+ log_file.sync = true
39
+ @logger = Logger.new(log_file)
40
+ end
41
+ end
42
+
43
+ def configure_temp_dir
44
+ @temp_dir = Dir.mktmpdir
45
+ ENV["TMPDIR"] = @temp_dir
46
+ FileUtils.mkdir_p(@temp_dir)
47
+ at_exit { FileUtils.rm_rf(@temp_dir) }
48
+ end
49
+
50
+ def init_database
51
+ @migrations_dir = File.expand_path("../../db/migrations", __FILE__)
52
+
53
+ Sequel.extension :migration
54
+
55
+ @db = Sequel.sqlite(:database => nil, :max_connections => 32, :pool_timeout => 10)
56
+ @db.loggers << @logger
57
+ Bosh::OpenstackRegistry.db = @db
58
+
59
+ run_migrations
60
+ end
61
+
62
+ def run_migrations
63
+ Sequel::Migrator.apply(@db, @migrations_dir, nil)
64
+ end
65
+
66
+ def reset_database
67
+ @db.execute("PRAGMA foreign_keys = OFF")
68
+ @db.tables.each do |table|
69
+ @db.drop_table(table)
70
+ end
71
+ @db.execute("PRAGMA foreign_keys = ON")
72
+ end
73
+
74
+ def reset
75
+ reset_database
76
+ run_migrations
77
+
78
+ Bosh::OpenstackRegistry.db = @db
79
+ Bosh::OpenstackRegistry.logger = @logger
80
+ end
81
+ end
82
+ end
83
+
84
+ SpecHelper.init
85
+
86
+ def valid_config
87
+ {
88
+ "logfile" => nil,
89
+ "loglevel" => "debug",
90
+ "http" => {
91
+ "user" => "admin",
92
+ "password" => "admin",
93
+ "port" => 25777
94
+ },
95
+ "db" => {
96
+ "max_connections" => 433,
97
+ "pool_timeout" => 227,
98
+ "database" => "sqlite:///:memory:"
99
+ },
100
+ "openstack" => {
101
+ "auth_url" => "http://127.0.0.1:5000/v2.0/tokens",
102
+ "username" => "foo",
103
+ "api_key" => "bar",
104
+ "tenant" => "foo"
105
+ }
106
+ }
107
+ end
108
+
109
+ RSpec.configure do |rspec|
110
+ rspec.before(:each) do
111
+ SpecHelper.reset
112
+ Bosh::OpenstackRegistry.logger = Logger.new(StringIO.new)
113
+ end
114
+ end
@@ -0,0 +1,74 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ require File.expand_path("../../spec_helper", __FILE__)
4
+
5
+ describe Bosh::OpenstackRegistry::ApiController do
6
+
7
+ before(:each) do
8
+ Bosh::OpenstackRegistry.http_user = "admin"
9
+ Bosh::OpenstackRegistry.http_password = "admin"
10
+
11
+ @server_manager = mock("server manager")
12
+ Bosh::OpenstackRegistry::ServerManager.stub!(:new).and_return(@server_manager)
13
+
14
+ rack_mock = Rack::MockSession.new(Bosh::OpenstackRegistry::ApiController.new)
15
+ @session = Rack::Test::Session.new(rack_mock)
16
+ end
17
+
18
+ def expect_json_response(response, status, body)
19
+ response.status.should == status
20
+ Yajl::Parser.parse(response.body).should == body
21
+ end
22
+
23
+ it "returns settings for given OpenStack server (IP check)" do
24
+ @server_manager.should_receive(:read_settings).
25
+ with("foo").and_return("bar")
26
+
27
+ @session.get("/servers/foo/settings")
28
+
29
+ expect_json_response(@session.last_response, 200,
30
+ { "status" => "ok", "settings" => "bar" })
31
+ end
32
+
33
+ it "returns settings (authorized user, no IP check)" do
34
+ @server_manager.should_receive(:read_settings).
35
+ with("foo").and_return("bar")
36
+
37
+ @session.basic_authorize("admin", "admin")
38
+ @session.get("/servers/foo/settings")
39
+
40
+ expect_json_response(@session.last_response, 200,
41
+ { "status" => "ok", "settings" => "bar" })
42
+ end
43
+
44
+ it "updates settings" do
45
+ @session.put("/servers/foo/settings", {}, { :input => "bar" })
46
+ expect_json_response(@session.last_response, 401,
47
+ { "status" => "access_denied" })
48
+
49
+ @server_manager.should_receive(:update_settings).
50
+ with("foo", "bar").and_return(true)
51
+
52
+ @session.basic_authorize("admin", "admin")
53
+ @session.put("/servers/foo/settings", {}, { :input => "bar" })
54
+
55
+ expect_json_response(@session.last_response, 200,
56
+ { "status" => "ok" })
57
+ end
58
+
59
+ it "deletes settings" do
60
+ @session.delete("/servers/foo/settings")
61
+ expect_json_response(@session.last_response, 401,
62
+ { "status" => "access_denied" })
63
+
64
+ @server_manager.should_receive(:delete_settings).
65
+ with("foo").and_return(true)
66
+
67
+ @session.basic_authorize("admin", "admin")
68
+ @session.delete("/servers/foo/settings")
69
+
70
+ expect_json_response(@session.last_response, 200,
71
+ { "status" => "ok" })
72
+ end
73
+
74
+ end
@@ -0,0 +1,56 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ require File.expand_path("../../spec_helper", __FILE__)
4
+
5
+ describe Bosh::OpenstackRegistry do
6
+
7
+ describe "configuring OpenStack registry" do
8
+ it "reads provided configuration file and sets singletons" do
9
+ Bosh::OpenstackRegistry.configure(valid_config)
10
+
11
+ logger = Bosh::OpenstackRegistry.logger
12
+
13
+ logger.should be_kind_of(Logger)
14
+ logger.level.should == Logger::DEBUG
15
+
16
+ Bosh::OpenstackRegistry.http_port.should == 25777
17
+ Bosh::OpenstackRegistry.http_user.should == "admin"
18
+ Bosh::OpenstackRegistry.http_password.should == "admin"
19
+
20
+ db = Bosh::OpenstackRegistry.db
21
+ db.should be_kind_of(Sequel::SQLite::Database)
22
+ db.opts[:database].should == "/:memory:"
23
+ db.opts[:max_connections].should == 433
24
+ db.opts[:pool_timeout].should == 227
25
+ end
26
+
27
+ it "validates configuration file" do
28
+ expect {
29
+ Bosh::OpenstackRegistry.configure("foobar")
30
+ }.to raise_error(Bosh::OpenstackRegistry::ConfigError,
31
+ /Invalid config format/)
32
+
33
+ config = valid_config.merge("http" => nil)
34
+
35
+ expect {
36
+ Bosh::OpenstackRegistry.configure(config)
37
+ }.to raise_error(Bosh::OpenstackRegistry::ConfigError,
38
+ /HTTP configuration is missing/)
39
+
40
+ config = valid_config.merge("db" => nil)
41
+
42
+ expect {
43
+ Bosh::OpenstackRegistry.configure(config)
44
+ }.to raise_error(Bosh::OpenstackRegistry::ConfigError,
45
+ /Database configuration is missing/)
46
+
47
+ config = valid_config.merge("openstack" => nil)
48
+
49
+ expect {
50
+ Bosh::OpenstackRegistry.configure(config)
51
+ }.to raise_error(Bosh::OpenstackRegistry::ConfigError,
52
+ /OpenStack configuration is missing/)
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,82 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ require File.expand_path("../../spec_helper", __FILE__)
4
+
5
+ describe Bosh::OpenstackRegistry::Runner do
6
+
7
+ def make_runner(config_file)
8
+ Bosh::OpenstackRegistry::Runner.new(config_file)
9
+ end
10
+
11
+ def write_config(file, config)
12
+ File.open(file, "w") do |f|
13
+ YAML.dump(config, f)
14
+ end
15
+ end
16
+
17
+ describe "initializing" do
18
+ it "configures OpenStack registry using provided file" do
19
+ config_file = Tempfile.new("config")
20
+ config = { "key" => "value" }
21
+ write_config(config_file.path, config)
22
+
23
+ Bosh::OpenstackRegistry.should_receive(:configure).with(config)
24
+ make_runner(config_file.path)
25
+ end
26
+
27
+ it "fails if config file not found" do
28
+ expect {
29
+ make_runner("foo")
30
+ }.to raise_error(Bosh::OpenstackRegistry::ConfigError, "Cannot find file `foo'")
31
+ end
32
+
33
+ it "fails when config file has incorrect format" do
34
+ config_file = Tempfile.new("config")
35
+ config = "foo"
36
+ write_config(config_file.path, config)
37
+
38
+ expect {
39
+ make_runner(config_file.path)
40
+ }.to raise_error(Bosh::OpenstackRegistry::ConfigError, /Incorrect file format/)
41
+ end
42
+
43
+ it "fails when some syscall fails" do
44
+ config_file = Tempfile.new("config")
45
+ write_config(config_file.path, { "foo" => "bar" })
46
+
47
+ YAML.stub!(:load_file).and_raise(SystemCallError.new("baz"))
48
+
49
+ expect {
50
+ make_runner(config_file.path)
51
+ }.to raise_error(Bosh::OpenstackRegistry::ConfigError, /baz/)
52
+ end
53
+ end
54
+
55
+ describe "running/stopping" do
56
+ before(:each) do
57
+ @config_file = Tempfile.new("config")
58
+ write_config(@config_file.path, valid_config)
59
+ end
60
+
61
+ it "spins up/shuts down reactor and HTTP server" do
62
+ runner = make_runner(@config_file)
63
+ mock_thin = mock("thin")
64
+
65
+ EM.should_receive(:run).and_yield
66
+
67
+ Thin::Server.should_receive(:new).
68
+ with("0.0.0.0", 25777, :signals => false).
69
+ and_return(mock_thin)
70
+
71
+ mock_thin.should_receive(:start!)
72
+
73
+ runner.run
74
+
75
+ mock_thin.should_receive(:stop!)
76
+ EM.should_receive(:stop)
77
+
78
+ runner.stop
79
+ end
80
+ end
81
+
82
+ end
@@ -0,0 +1,69 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ require File.expand_path("../../spec_helper", __FILE__)
4
+
5
+ describe Bosh::OpenstackRegistry::ServerManager do
6
+
7
+ before(:each) do
8
+ openstack = double(Fog::Compute)
9
+ Fog::Compute.stub(:new).and_return(openstack)
10
+ @openstack = mock("openstack")
11
+ Bosh::OpenstackRegistry.openstack = @openstack
12
+ end
13
+
14
+ let(:manager) do
15
+ Bosh::OpenstackRegistry::ServerManager.new
16
+ end
17
+
18
+ def create_server(params)
19
+ Bosh::OpenstackRegistry::Models::OpenstackServer.create(params)
20
+ end
21
+
22
+ describe "reading settings" do
23
+ it "returns settings" do
24
+ create_server(:server_id => "foo", :settings => "bar")
25
+ manager.read_settings("foo").should == "bar"
26
+ end
27
+
28
+ it "raises an error if server not found" do
29
+ expect {
30
+ manager.read_settings("foo")
31
+ }.to raise_error(Bosh::OpenstackRegistry::ServerNotFound,
32
+ "Can't find server `foo'")
33
+ end
34
+ end
35
+
36
+ describe "updating settings" do
37
+ it "updates settings (new server)" do
38
+ manager.update_settings("foo", "baz")
39
+ manager.read_settings("foo").should == "baz"
40
+ end
41
+
42
+ it "updates settings (existing server)" do
43
+ create_server(:server_id => "foo", :settings => "bar")
44
+ manager.read_settings("foo").should == "bar"
45
+ manager.update_settings("foo", "baz")
46
+ manager.read_settings("foo").should == "baz"
47
+ end
48
+ end
49
+
50
+ describe "deleting settings" do
51
+ it "deletes settings" do
52
+ manager.update_settings("foo", "baz")
53
+ manager.delete_settings("foo")
54
+
55
+ expect {
56
+ manager.read_settings("foo")
57
+ }.to raise_error(Bosh::OpenstackRegistry::ServerNotFound,
58
+ "Can't find server `foo'")
59
+ end
60
+
61
+ it "raises an error if server not found" do
62
+ expect {
63
+ manager.delete_settings("foo")
64
+ }.to raise_error(Bosh::OpenstackRegistry::ServerNotFound,
65
+ "Can't find server `foo'")
66
+ end
67
+ end
68
+
69
+ end
metadata ADDED
@@ -0,0 +1,157 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bosh_openstack_registry
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - VMware
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sequel
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: sinatra
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: thin
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: yajl-ruby
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: fog
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 1.4.0
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 1.4.0
94
+ description: BOSH OpenStack registry
95
+ email: support@vmware.com
96
+ executables:
97
+ - openstack_registry
98
+ extensions: []
99
+ extra_rdoc_files: []
100
+ files:
101
+ - bin/migrate
102
+ - bin/openstack_registry
103
+ - lib/openstack_registry.rb
104
+ - lib/openstack_registry/api_controller.rb
105
+ - lib/openstack_registry/config.rb
106
+ - lib/openstack_registry/errors.rb
107
+ - lib/openstack_registry/models.rb
108
+ - lib/openstack_registry/models/openstack_server.rb
109
+ - lib/openstack_registry/runner.rb
110
+ - lib/openstack_registry/server_manager.rb
111
+ - lib/openstack_registry/version.rb
112
+ - lib/openstack_registry/yaml_helper.rb
113
+ - README
114
+ - Rakefile
115
+ - spec/assets/sample_config.yml
116
+ - spec/spec_helper.rb
117
+ - spec/unit/api_controller_spec.rb
118
+ - spec/unit/config_spec.rb
119
+ - spec/unit/runner_spec.rb
120
+ - spec/unit/server_manager_spec.rb
121
+ homepage: http://www.vmware.com
122
+ licenses: []
123
+ post_install_message:
124
+ rdoc_options: []
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ none: false
129
+ requirements:
130
+ - - ! '>='
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ segments:
134
+ - 0
135
+ hash: -1851942175393583791
136
+ required_rubygems_version: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ segments:
143
+ - 0
144
+ hash: -1851942175393583791
145
+ requirements: []
146
+ rubyforge_project:
147
+ rubygems_version: 1.8.24
148
+ signing_key:
149
+ specification_version: 3
150
+ summary: BOSH OpenStack registry
151
+ test_files:
152
+ - spec/assets/sample_config.yml
153
+ - spec/spec_helper.rb
154
+ - spec/unit/api_controller_spec.rb
155
+ - spec/unit/config_spec.rb
156
+ - spec/unit/runner_spec.rb
157
+ - spec/unit/server_manager_spec.rb