bosh-registry 1.5.0.pre.1113

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []