bosh-registry 1.5.0.pre.1113

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,105 @@
1
+ # BOSH Registry
2
+ Copyright (c) 2009-2013 VMware, Inc.
3
+
4
+ For online documentation see: http://rubydoc.info/gems/bosh-registry/
5
+
6
+ ## Usage
7
+
8
+ bin/bosh-registry-migrate [<options>]
9
+ -c, --config FILE Bosh Registry configuration file
10
+
11
+ bin/bosh-registry [<options>]
12
+ -c, --config FILE Bosh Registry configuration file
13
+
14
+ ## Configuration
15
+
16
+ These options are passed to the Bosh Registry when it is instantiated.
17
+
18
+ ### Registry options
19
+
20
+ These are the options for the Registry HTTP server (by default server is
21
+ bound to address 0.0.0.0):
22
+
23
+ * `port` (required)
24
+ Registry port
25
+ * `user` (required)
26
+ Registry user (for HTTP Basic authentication)
27
+ * `password` (required)
28
+ Registry password (for HTTP Basic authentication)
29
+
30
+ ### Database options
31
+
32
+ These are the options for the database connection where registry will store
33
+ instance properties:
34
+
35
+ * `database` (required)
36
+ DB connection URI
37
+ * `max_connections` (required)
38
+ Maximum size of the connection pool
39
+ * `pool_timeout` (required)
40
+ Number of seconds to wait if a connection cannot be acquired before
41
+ raising an error
42
+
43
+ ### Cloud options
44
+
45
+ These are the options for the cloud connection where registry will fetch for
46
+ the IP addresses belonging to a instances:
47
+
48
+ * `plugin` (required)
49
+ Cloud Provider (currently supported: aws and openstack)
50
+
51
+ #### AWS options
52
+
53
+ These are the credentials to connect to AWS services:
54
+
55
+ * `access_key_id` (required)
56
+ IAM Access Key ID
57
+ * `secret_access_key` (required)
58
+ AWS IAM Secret Access Key
59
+ * `region` (required)
60
+ AWS EC2 Region
61
+ * `max_retries` (optional, defaults to 2)
62
+ Max number of retries to connect to AWS
63
+
64
+ #### OpenStack options
65
+
66
+ These are the credentials to connect to OpenStack services:
67
+
68
+ * `auth_url` (required)
69
+ URL of the OpenStack Identity endpoint to connect to
70
+ * `username` (required)
71
+ OpenStack user name
72
+ * `api_key` (required)
73
+ OpenStack API key
74
+ * `tenant` (required)
75
+ OpenStack tenant name
76
+ * `region` (optional)
77
+ OpenStack region
78
+ * `endpoint_type` (optional)
79
+ OpenStack endpoint type (publicURL (default), adminURL, internalURL)
80
+
81
+ ## Example
82
+
83
+ This is a sample of an Bosh Registry configuration file:
84
+
85
+ ---
86
+ loglevel: debug
87
+
88
+ http:
89
+ port: 25695
90
+ user: admin
91
+ password: admin
92
+
93
+ db:
94
+ database: "sqlite:///:memory:"
95
+ max_connections: 32
96
+ pool_timeout: 10
97
+
98
+ cloud:
99
+ plugin: openstack
100
+ openstack:
101
+ auth_url: "http://127.0.0.1:5000/v2.0"
102
+ username: foo
103
+ api_key: bar
104
+ tenant: foo
105
+ region:
data/bin/bosh-registry ADDED
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bosh/registry"
4
+ require "optparse"
5
+
6
+ config_file = nil
7
+
8
+ opts = OptionParser.new do |opts|
9
+ opts.on("-c", "--config FILE", "configuration file") do |opt|
10
+ config_file = opt
11
+ end
12
+ end
13
+
14
+ opts.parse!(ARGV.dup)
15
+
16
+ if config_file.nil?
17
+ puts opts
18
+ exit 1
19
+ end
20
+
21
+ runner = Bosh::Registry::Runner.new(config_file)
22
+
23
+ Signal.trap("INT") do
24
+ runner.stop
25
+ exit(1)
26
+ end
27
+
28
+ runner.run
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "logger"
4
+ require "sequel"
5
+ require "bosh/registry"
6
+ require "optparse"
7
+
8
+ config_file = nil
9
+
10
+ opts = OptionParser.new do |opts|
11
+ opts.on("-c", "--config FILE", "configuration file") do |opt|
12
+ config_file = opt
13
+ end
14
+ end
15
+
16
+ opts.parse!(ARGV.dup)
17
+
18
+ if config_file.nil?
19
+ puts opts
20
+ exit 1
21
+ end
22
+
23
+ include Bosh::Registry::YamlHelper
24
+
25
+ config = load_yaml_file(config_file)
26
+
27
+ db = Bosh::Registry.connect_db(config["db"])
28
+ migrations_dir = File.expand_path("../../db/migrations", __FILE__)
29
+
30
+ options = {
31
+ :table => "registry_schema"
32
+ }
33
+
34
+ Sequel.extension :migration
35
+ Sequel::TimestampMigrator.run(db, migrations_dir, options)
@@ -0,0 +1,12 @@
1
+ # Copyright (c) 2009-2013 VMware, Inc.
2
+
3
+ Sequel.migration do
4
+ change do
5
+ create_table :registry_instances do
6
+ primary_key :id
7
+
8
+ String :instance_id, :null => false, :unique => true
9
+ String :settings, :null => false, :text => true
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,26 @@
1
+ # Copyright (c) 2009-2013 VMware, Inc.
2
+
3
+ module Bosh
4
+ module Registry
5
+ autoload :Models, "bosh/registry/models"
6
+ end
7
+ end
8
+
9
+ require "aws-sdk"
10
+ require "fog"
11
+ require "logger"
12
+ require "sequel"
13
+ require "sinatra/base"
14
+ require "thin"
15
+ require "yajl"
16
+
17
+ require "bosh/registry/yaml_helper"
18
+
19
+ require "bosh/registry/api_controller"
20
+ require "bosh/registry/config"
21
+ require "bosh/registry/errors"
22
+ require "bosh/registry/instance_manager"
23
+ require "bosh/registry/runner"
24
+ require "bosh/registry/version"
25
+
26
+ Sequel::Model.plugin :validation_helpers
@@ -0,0 +1,68 @@
1
+ # Copyright (c) 2009-2013 VMware, Inc.
2
+
3
+ module Bosh::Registry
4
+
5
+ class ApiController < Sinatra::Base
6
+
7
+ not_found do
8
+ exception = request.env["sinatra.error"]
9
+ @logger.error(exception.message)
10
+ json(:status => "not_found")
11
+ end
12
+
13
+ error do
14
+ exception = request.env["sinatra.error"]
15
+ @logger.error(exception)
16
+ status(500)
17
+ json(:status => "error")
18
+ end
19
+
20
+ get "/instances/:instance_id/settings" do
21
+ ip_check = authorized? ? nil : request.ip
22
+ settings = @instance_manager.read_settings(params[:instance_id], ip_check)
23
+ json(:status => "ok", :settings => settings)
24
+ end
25
+
26
+ put "/instances/:instance_id/settings" do
27
+ protected!
28
+ @instance_manager.update_settings(params[:instance_id], request.body.read)
29
+ json(:status => "ok")
30
+ end
31
+
32
+ delete "/instances/:instance_id/settings" do
33
+ protected!
34
+ @instance_manager.delete_settings(params[:instance_id]) rescue InstanceNotFound
35
+ json(:status => "ok")
36
+ end
37
+
38
+ def initialize
39
+ super
40
+ @logger = Bosh::Registry.logger
41
+
42
+ @users = Set.new
43
+ @users << [Bosh::Registry.http_user, Bosh::Registry.http_password]
44
+ @instance_manager = Bosh::Registry.instance_manager
45
+ end
46
+
47
+ def protected!
48
+ unless authorized?
49
+ headers("WWW-Authenticate" => 'Basic realm="Bosh Registry"')
50
+ halt(401, json("status" => "access_denied"))
51
+ end
52
+ end
53
+
54
+ def authorized?
55
+ @auth ||= Rack::Auth::Basic::Request.new(request.env)
56
+ @auth.provided? &&
57
+ @auth.basic? &&
58
+ @auth.credentials &&
59
+ @users.include?(@auth.credentials)
60
+ end
61
+
62
+ def json(payload)
63
+ Yajl::Encoder.encode(payload)
64
+ end
65
+
66
+ end
67
+
68
+ end
@@ -0,0 +1,124 @@
1
+ # Copyright (c) 2009-2013 VMware, Inc.
2
+ # Copyright (c) 2012 Piston Cloud Computing, Inc.
3
+ require 'httpclient'
4
+ require 'cloud/errors'
5
+ require 'base64'
6
+
7
+ module Bosh::Registry
8
+ ##
9
+ # Represents Bosh Registry Client. It performs CRUD operations against
10
+ # the OpenStack Registry.
11
+ #
12
+ # Settings example:
13
+ # settings = {
14
+ # "vm" => {
15
+ # "name" => server_name
16
+ # },
17
+ # "agent_id" => agent_id,
18
+ # "networks" => network_spec,
19
+ # "disks" => {
20
+ # "system" => "/dev/vda",
21
+ # "ephemeral" => "/dev/vdb",
22
+ # "persistent" => {"volume_id" => device_name}
23
+ # }
24
+ # }
25
+ class Client
26
+ attr_reader :endpoint
27
+ attr_reader :user
28
+ attr_reader :password
29
+
30
+ def initialize(endpoint, user, password)
31
+ @endpoint = endpoint
32
+
33
+ unless @endpoint =~ /^http:\/\//
34
+ @endpoint = "http://#{@endpoint}"
35
+ end
36
+
37
+ @user = user
38
+ @password = password
39
+
40
+ auth = Base64.encode64("#{@user}:#{@password}").gsub("\n", '')
41
+
42
+ @headers = {
43
+ "Accept" => 'application/json',
44
+ "Authorization" => "Basic #{auth}"
45
+ }
46
+
47
+ @client = HTTPClient.new
48
+ end
49
+
50
+ ##
51
+ # Update instance settings in the registry
52
+ # @param [String] instance_id EC2 instance id
53
+ # @param [Hash] settings New agent settings
54
+ # @return [Boolean]
55
+ def update_settings(instance_id, settings)
56
+ unless settings.is_a?(Hash)
57
+ raise ArgumentError, "Invalid settings format, Hash expected, #{settings.class} given"
58
+ end
59
+
60
+ payload = Yajl::Encoder.encode(settings)
61
+ url = "#{@endpoint}/instances/#{instance_id}/settings"
62
+
63
+ response = @client.put(url, {:body => payload, :header => @headers})
64
+
65
+ if response.status != 200
66
+ cloud_error("Cannot update settings for '#{instance_id}', got HTTP #{response.status}")
67
+ end
68
+
69
+ true
70
+ end
71
+
72
+ ##
73
+ # Read instance settings from the registry
74
+ # @param [String] instance_id EC2 instance id
75
+ # @return [Hash] Agent settings
76
+ def read_settings(instance_id)
77
+ url = "#{@endpoint}/instances/#{instance_id}/settings"
78
+
79
+ response = @client.get(url, {:header => @headers})
80
+
81
+ if response.status != 200
82
+ cloud_error("Cannot read settings for '#{instance_id}', got HTTP #{response.status}")
83
+ end
84
+
85
+ body = Yajl::Parser.parse(response.body)
86
+
87
+ unless body.is_a?(Hash)
88
+ cloud_error("Invalid registry response, Hash expected, got #{body.class}: #{body}")
89
+ end
90
+
91
+ settings = Yajl::Parser.parse(body["settings"])
92
+
93
+ unless settings.is_a?(Hash)
94
+ cloud_error("Invalid settings format, Hash expected, got #{settings.class}: #{settings}")
95
+ end
96
+
97
+ settings
98
+ rescue Yajl::ParseError => e
99
+ cloud_error("Cannot parse settings for '#{instance_id}': #{e.message}")
100
+ end
101
+
102
+ ##
103
+ # Delete instance settings from the registry
104
+ # @param [String] instance_id EC2 instance id
105
+ # @return [Boolean]
106
+ def delete_settings(instance_id)
107
+ url = "#{@endpoint}/instances/#{instance_id}/settings"
108
+
109
+ response = @client.delete(url, {:header => @headers})
110
+
111
+ if response.status != 200
112
+ cloud_error("Cannot delete settings for '#{instance_id}', got HTTP #{response.status}")
113
+ end
114
+
115
+ true
116
+ end
117
+
118
+ private
119
+
120
+ def cloud_error(message)
121
+ raise Bosh::Clouds::CloudError, message
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,76 @@
1
+ # Copyright (c) 2009-2013 VMware, Inc.
2
+
3
+ module Bosh::Registry
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
+ attr_accessor :instance_manager
13
+
14
+ def configure(config)
15
+ validate_config(config)
16
+
17
+ @logger ||= Logger.new(config["logfile"] || STDOUT)
18
+ if config["loglevel"].kind_of?(String)
19
+ @logger.level = Logger.const_get(config["loglevel"].upcase)
20
+ end
21
+
22
+ @http_port = config["http"]["port"]
23
+ @http_user = config["http"]["user"]
24
+ @http_password = config["http"]["password"]
25
+
26
+ @db = connect_db(config["db"])
27
+
28
+ plugin = config["cloud"]["plugin"]
29
+ begin
30
+ require "bosh/registry/instance_manager/#{plugin}"
31
+ rescue LoadError
32
+ raise ConfigError, "Could not find Provider Plugin: #{plugin}"
33
+ end
34
+ @instance_manager = Bosh::Registry::InstanceManager.const_get(plugin.capitalize).new(config["cloud"])
35
+ end
36
+
37
+ def connect_db(db_config)
38
+ connection_options = db_config.delete('connection_options') {{}}
39
+ db_config.delete_if { |_, v| v.to_s.empty? }
40
+ db_config = db_config.merge(connection_options)
41
+
42
+ db = Sequel.connect(db_config)
43
+ if logger
44
+ db.logger = @logger
45
+ db.sql_log_level = :debug
46
+ end
47
+
48
+ db
49
+ end
50
+
51
+ def validate_config(config)
52
+ unless config.is_a?(Hash)
53
+ raise ConfigError, "Invalid config format, Hash expected, " \
54
+ "#{config.class} given"
55
+ end
56
+
57
+ unless config.has_key?("http") && config["http"].is_a?(Hash)
58
+ raise ConfigError, "HTTP configuration is missing from config file"
59
+ end
60
+
61
+ unless config.has_key?("db") && config["db"].is_a?(Hash)
62
+ raise ConfigError, "Database configuration is missing from config file"
63
+ end
64
+
65
+ unless config.has_key?("cloud") && config["cloud"].is_a?(Hash)
66
+ raise ConfigError, "Cloud configuration is missing from config file"
67
+ end
68
+
69
+ if config["cloud"]["plugin"].nil?
70
+ raise ConfigError, "Cloud plugin is missing from config file"
71
+ end
72
+ end
73
+
74
+ end
75
+
76
+ end
@@ -0,0 +1,20 @@
1
+ # Copyright (c) 2009-2013 VMware, Inc.
2
+
3
+ module Bosh::Registry
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 AWSError < Error; end
17
+
18
+ class InstanceError < Error; end
19
+ class InstanceNotFound < Error; code(404); end
20
+ end
@@ -0,0 +1,65 @@
1
+ # Copyright (c) 2009-2013 VMware, Inc.
2
+
3
+ module Bosh::Registry
4
+
5
+ class InstanceManager
6
+
7
+ ##
8
+ # Updates instance settings
9
+ # @param [String] instance_id instance id (instance record
10
+ # will be created in DB if it doesn't already exist)
11
+ # @param [String] settings New settings for the instance
12
+ def update_settings(instance_id, settings)
13
+ params = {
14
+ :instance_id => instance_id
15
+ }
16
+
17
+ instance = Models::RegistryInstance[params] || Models::RegistryInstance.new(params)
18
+ instance.settings = settings
19
+ instance.save
20
+ end
21
+
22
+ ##
23
+ # Reads instance settings
24
+ # @param [String] instance_id instance id
25
+ # @param [optional, String] remote_ip If this IP is provided,
26
+ # check will be performed to see if it instance id
27
+ # actually has this IP address according to the IaaS.
28
+ def read_settings(instance_id, remote_ip = nil)
29
+ check_instance_ips(remote_ip, instance_id) if remote_ip
30
+
31
+ get_instance(instance_id).settings
32
+ end
33
+
34
+ ##
35
+ # Seletes instance settings
36
+ # @param [String] instance_id instance id
37
+ def delete_settings(instance_id)
38
+ get_instance(instance_id).destroy
39
+ end
40
+
41
+ private
42
+
43
+ def check_instance_ips(ip, instance_id)
44
+ return if ip == "127.0.0.1"
45
+ actual_ips = instance_ips(instance_id)
46
+ unless actual_ips.include?(ip)
47
+ raise InstanceError, "Instance IP mismatch, expected IP is " \
48
+ "`%s', actual IP(s): `%s'" %
49
+ [ ip, actual_ips.join(", ") ]
50
+ end
51
+ end
52
+
53
+ def get_instance(instance_id)
54
+ instance = Models::RegistryInstance[:instance_id => instance_id]
55
+
56
+ if instance.nil?
57
+ raise InstanceNotFound, "Can't find instance `#{instance_id}'"
58
+ end
59
+
60
+ instance
61
+ end
62
+
63
+ end
64
+
65
+ end
@@ -0,0 +1,53 @@
1
+ # Copyright (c) 2009-2013 VMware, Inc.
2
+
3
+ module Bosh::Registry
4
+
5
+ class InstanceManager
6
+
7
+ class Aws < InstanceManager
8
+
9
+ AWS_MAX_RETRIES = 2
10
+
11
+ def initialize(cloud_config)
12
+ validate_options(cloud_config)
13
+
14
+ @logger = Bosh::Registry.logger
15
+
16
+ @aws_properties = cloud_config["aws"]
17
+ @aws_options = {
18
+ :access_key_id => @aws_properties["access_key_id"],
19
+ :secret_access_key => @aws_properties["secret_access_key"],
20
+ :max_retries => @aws_properties["max_retries"] || AWS_MAX_RETRIES,
21
+ :ec2_endpoint => "ec2.#{@aws_properties['region']}.amazonaws.com",
22
+ :logger => @logger
23
+ }
24
+ @ec2 = AWS::EC2.new(@aws_options)
25
+ end
26
+
27
+ def validate_options(cloud_config)
28
+ unless cloud_config.has_key?("aws") &&
29
+ cloud_config["aws"].is_a?(Hash) &&
30
+ cloud_config["aws"]["access_key_id"] &&
31
+ cloud_config["aws"]["secret_access_key"] &&
32
+ cloud_config["aws"]["region"]
33
+ raise ConfigError, "Invalid AWS configuration parameters"
34
+ end
35
+ end
36
+
37
+ # Get the list of IPs belonging to this instance
38
+ def instance_ips(instance_id)
39
+ instance = @ec2.instances[instance_id]
40
+ ips = [instance.private_ip_address, instance.public_ip_address]
41
+ if instance.has_elastic_ip?
42
+ ips << instance.elastic_ip.public_ip
43
+ end
44
+ ips
45
+ rescue AWS::Errors::Base => e
46
+ raise Bosh::Registry::AwsError, "AWS error: #{e}"
47
+ end
48
+
49
+ end
50
+
51
+ end
52
+
53
+ end
@@ -0,0 +1,69 @@
1
+ # Copyright (c) 2009-2013 VMware, Inc.
2
+
3
+ module Bosh::Registry
4
+
5
+ class InstanceManager
6
+
7
+ class Openstack < InstanceManager
8
+
9
+ def initialize(cloud_config)
10
+ validate_options(cloud_config)
11
+
12
+ @logger = Bosh::Registry.logger
13
+
14
+ @openstack_properties = cloud_config["openstack"]
15
+
16
+ unless @openstack_properties["auth_url"].match(/\/tokens$/)
17
+ @openstack_properties["auth_url"] = @openstack_properties["auth_url"] + "/tokens"
18
+ end
19
+
20
+ @openstack_options = {
21
+ :provider => "OpenStack",
22
+ :openstack_auth_url => @openstack_properties["auth_url"],
23
+ :openstack_username => @openstack_properties["username"],
24
+ :openstack_api_key => @openstack_properties["api_key"],
25
+ :openstack_tenant => @openstack_properties["tenant"],
26
+ :openstack_region => @openstack_properties["region"],
27
+ :openstack_endpoint_type => @openstack_properties["endpoint_type"]
28
+ }
29
+ end
30
+
31
+ def openstack
32
+ @openstack ||= Fog::Compute.new(@openstack_options)
33
+ end
34
+
35
+ def validate_options(cloud_config)
36
+ unless cloud_config.has_key?("openstack") &&
37
+ cloud_config["openstack"].is_a?(Hash) &&
38
+ cloud_config["openstack"]["auth_url"] &&
39
+ cloud_config["openstack"]["username"] &&
40
+ cloud_config["openstack"]["api_key"] &&
41
+ cloud_config["openstack"]["tenant"]
42
+ raise ConfigError, "Invalid OpenStack configuration parameters"
43
+ end
44
+ end
45
+
46
+ # Get the list of IPs belonging to this instance
47
+ def instance_ips(instance_id)
48
+ # If we get an Unauthorized error, it could mean that the OpenStack auth token has expired, so we are
49
+ # going renew the fog connection one time to make sure that we get a new non-expired token.
50
+ retried = false
51
+ begin
52
+ instance = openstack.servers.find { |s| s.name == instance_id }
53
+ rescue Excon::Errors::Unauthorized => e
54
+ unless retried
55
+ retried = true
56
+ @openstack = nil
57
+ retry
58
+ end
59
+ raise ConnectionError, "Unable to connect to OpenStack API: #{e.message}"
60
+ end
61
+ raise InstanceNotFound, "Instance `#{instance_id}' not found" unless instance
62
+ return (instance.private_ip_addresses + instance.floating_ip_addresses).compact
63
+ end
64
+
65
+ end
66
+
67
+ end
68
+
69
+ end
@@ -0,0 +1,8 @@
1
+ # Copyright (c) 2009-2013 VMware, Inc.
2
+
3
+ module Bosh::Registry
4
+ module Models
5
+ end
6
+ end
7
+
8
+ require "bosh/registry/models/registry_instance"
@@ -0,0 +1,12 @@
1
+ # Copyright (c) 2009-2013 VMware, Inc.
2
+
3
+ module Bosh::Registry::Models
4
+ class RegistryInstance < Sequel::Model
5
+
6
+ def validate
7
+ validates_presence [:instance_id, :settings]
8
+ validates_unique :instance_id
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,48 @@
1
+ # Copyright (c) 2009-2013 VMware, Inc.
2
+
3
+ module Bosh::Registry
4
+ class Runner
5
+ include YamlHelper
6
+
7
+ def initialize(config_file)
8
+ Bosh::Registry.configure(load_yaml_file(config_file))
9
+
10
+ @logger = Bosh::Registry.logger
11
+ @http_port = Bosh::Registry.http_port
12
+ @http_user = Bosh::Registry.http_user
13
+ @http_password = Bosh::Registry.http_password
14
+ end
15
+
16
+ def run
17
+ @logger.info("BOSH Registry starting...")
18
+ start_http_server
19
+ end
20
+
21
+ def stop
22
+ @logger.info("BOSH Registry shutting down...")
23
+ @http_server.stop! if @http_server
24
+ end
25
+
26
+ def start_http_server
27
+ @logger.info "HTTP server is starting on port #{@http_port}..."
28
+ @http_server = Thin::Server.new("0.0.0.0", @http_port, :signals => false) do
29
+ Thin::Logging.silent = true
30
+ map "/" do
31
+ run Bosh::Registry::ApiController.new
32
+ end
33
+ end
34
+ @http_server.start!
35
+ end
36
+
37
+ private
38
+
39
+ def handle_em_error(e, level = :fatal)
40
+ @logger.send(level, e.to_s)
41
+ if e.respond_to?(:backtrace) && e.backtrace.respond_to?(:join)
42
+ @logger.send(level, e.backtrace.join("\n"))
43
+ end
44
+ stop
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,7 @@
1
+ # Copyright (c) 2009-2013 VMware, Inc.
2
+
3
+ module Bosh
4
+ module Registry
5
+ VERSION = '1.5.0.pre.1113'
6
+ end
7
+ end
@@ -0,0 +1,24 @@
1
+ # Copyright (c) 2009-2013 VMware, Inc.
2
+
3
+ module Bosh::Registry
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 = Psych.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
metadata ADDED
@@ -0,0 +1,162 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bosh-registry
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.5.0.pre.1113
5
+ prerelease: 6
6
+ platform: ruby
7
+ authors:
8
+ - VMware
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-10-16 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: 3.43.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: 3.43.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: 1.4.2
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: 1.4.2
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: 1.5.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: 1.5.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: 1.1.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: 1.1.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.14.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.14.0
94
+ - !ruby/object:Gem::Dependency
95
+ name: aws-sdk
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - '='
100
+ - !ruby/object:Gem::Version
101
+ version: 1.8.5
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - '='
108
+ - !ruby/object:Gem::Version
109
+ version: 1.8.5
110
+ description: ! 'BOSH Registry
111
+
112
+ cfd471'
113
+ email: support@cloudfoundry.com
114
+ executables:
115
+ - bosh-registry
116
+ - bosh-registry-migrate
117
+ extensions: []
118
+ extra_rdoc_files: []
119
+ files:
120
+ - db/migrations/20130306112035_create_registry_instances.rb
121
+ - lib/bosh/registry.rb
122
+ - lib/bosh/registry/api_controller.rb
123
+ - lib/bosh/registry/client.rb
124
+ - lib/bosh/registry/config.rb
125
+ - lib/bosh/registry/errors.rb
126
+ - lib/bosh/registry/instance_manager.rb
127
+ - lib/bosh/registry/instance_manager/aws.rb
128
+ - lib/bosh/registry/instance_manager/openstack.rb
129
+ - lib/bosh/registry/models.rb
130
+ - lib/bosh/registry/models/registry_instance.rb
131
+ - lib/bosh/registry/runner.rb
132
+ - lib/bosh/registry/version.rb
133
+ - lib/bosh/registry/yaml_helper.rb
134
+ - README.md
135
+ - bin/bosh-registry
136
+ - bin/bosh-registry-migrate
137
+ homepage: https://github.com/cloudfoundry/bosh
138
+ licenses:
139
+ - Apache 2.0
140
+ post_install_message:
141
+ rdoc_options: []
142
+ require_paths:
143
+ - lib
144
+ required_ruby_version: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: 1.9.3
150
+ required_rubygems_version: !ruby/object:Gem::Requirement
151
+ none: false
152
+ requirements:
153
+ - - ! '>'
154
+ - !ruby/object:Gem::Version
155
+ version: 1.3.1
156
+ requirements: []
157
+ rubyforge_project:
158
+ rubygems_version: 1.8.23
159
+ signing_key:
160
+ specification_version: 3
161
+ summary: BOSH Registry
162
+ test_files: []