Bumped vcap/servics to Services-R9

Conflicts:
	cloud_controller/Gemfile.lock

Change-Id: If7edf506fa8d67fcc0df81120fab9fbde469259d
This commit is contained in:
Nicholas Kushmerick 2012-03-23 08:11:21 -07:00
Родитель f3f5027095 d06f66cd12
Коммит 901c9685e9
34 изменённых файлов: 284 добавлений и 49 удалений

Просмотреть файл

@ -1,6 +0,0 @@
#!/usr/bin/env ruby
ENV['BUNDLE_GEMFILE'] = File.dirname(__FILE__) + '/../../services/rabbit/Gemfile'
$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../services/rabbit')
require 'rabbit_service'

Просмотреть файл

Просмотреть файл

4
bin/services/vblob_gateway Executable file
Просмотреть файл

@ -0,0 +1,4 @@
#!/usr/bin/env ruby
# Copyright (c) 2009-2012 VMware, Inc.
exec(File.expand_path("../../../services/vblob/bin/vblob_gateway", __FILE__), *ARGV)

4
bin/services/vblob_node Executable file
Просмотреть файл

@ -0,0 +1,4 @@
#!/usr/bin/env ruby
# Copyright (c) 2009-2012 VMware, Inc.
exec(File.expand_path("../../../services/vblob/bin/vblob_node", __FILE__), *ARGV)

Просмотреть файл

@ -134,7 +134,7 @@ GEM
polyglot (>= 0.3.1)
tzinfo (0.3.26)
uuidtools (2.1.2)
vcap_common (1.0.9)
vcap_common (1.0.10)
eventmachine (~> 0.12.11.cloudfoundry.3)
nats (~> 0.4.22.beta.8)
posix-spawn (~> 0.3.6)

Просмотреть файл

@ -38,7 +38,7 @@ class DefaultController < ApplicationController
ret[svc_type] ||= {}
ret[svc_type][svc.name] ||= {}
ret[svc_type][svc.name][svc.version] ||= {}
ret[svc_type][svc.name][svc.version] = svc.as_legacy
ret[svc_type][svc.name][svc.version] = svc.as_legacy(user)
end
render :json => ret

Просмотреть файл

@ -54,7 +54,7 @@ class LegacyServicesController < ApplicationController
# Legacy api fell back to matching by vendor if no version matched
svc ||= ::Service.find_by_name(req.vendor)
raise CloudError.new(CloudError::SERVICE_NOT_FOUND) unless svc && svc.visible_to_user?(user)
raise CloudError.new(CloudError::SERVICE_NOT_FOUND) unless svc && svc.visible_to_user?(user, req.tier)
plan_option = nil
if req.options && req.options['plan_option']

Просмотреть файл

@ -159,7 +159,7 @@ class ServicesController < ApplicationController
req = VCAP::Services::Api::CloudControllerProvisionRequest.decode(request_body)
svc = Service.find_by_label(req.label)
raise CloudError.new(CloudError::SERVICE_NOT_FOUND) unless svc && svc.visible_to_user?(user)
raise CloudError.new(CloudError::SERVICE_NOT_FOUND) unless svc && svc.visible_to_user?(user, req.plan)
cfg = ServiceConfig.provision(svc, user, req.name, req.plan, req.plan_option)

Просмотреть файл

@ -31,33 +31,73 @@ class Service < ActiveRecord::Base
# Predicate function that returns true if the service is visible to the supplied
# user. False otherwise.
#
# NB: This is currently a stub. When we implement scoped services it will be filled in.
def visible_to_user?(user)
(!self.acls || user_in_userlist?(user) || user_match_wildcards?(user))
# There are two parts of acls. One is service acls applied to service as a whole
# One is plan acls applied to specific service plan.
#
# A example of acls structure:
# acls:
# users: #service acls
# - foo@bar.com
# - foo1@bar.com
# wildcards: #service acls
# - *@foo.com
# - *@foo1.com
# plans:
# plan_a: #plan acls
# users:
# - foo2@foo.com
# wildcards:
# - *@foo1.com
#
# The following chart shows service visibility:
#
# P_ACLs\S_ACLs | Empty | HasACLs |
# Empty | True | S_ACL(user) |
# HasACLs | P_ACL(user) | S_ACL(user) && P_ACL(user) |
def visible_to_user?(user, plan=nil)
return false if !plans || !user.email
return true unless acls
if !plan
plans.each do |p|
return true if visible_to_user?(user, p)
end
return false
else
# for certain plan, user should match service acls and plan acls
p_acls = acls["plans"] && acls["plans"][plan]
validate_by_acls?(user, acls) && validate_by_acls?(user, p_acls)
end
end
# Return true if acls is empty or user matches user list or wildcards
# false otherwise.
def validate_by_acls?(user, acl)
!acl ||
(!acl["users"] && !acl["wildcards"]) ||
user_in_userlist?(user, acl["users"]) ||
user_match_wildcards?(user, acl["wildcards"])
end
# Returns true if the user's email is contained in the set of user emails
def user_in_userlist?(user)
return false if (!self.acls || self.acls['users'].empty? || !user.email)
return true if self.acls['users'].empty?
Set.new(self.acls['users']).include?(user.email)
# false otherwise
def user_in_userlist?(user, userlist)
userlist && userlist.include?(user.email)
end
# Returns true if user matches any of the wildcards, false otherwise.
def user_match_wildcards?(user)
return false if (!self.acls || self.acls['wildcards'].empty? || !user.email)
for wc in self.acls['wildcards']
parts = wc.split('*')
re_str = parts.map{|p| Regexp.escape(p)}.join('.*')
if Regexp.new("^#{re_str}$").match(user.email)
return true
end
end
# Returns true if user matches any of the wildcards
# false otherwise.
def user_match_wildcards?(user, wildcards)
wildcards.each do |wc|
re_str = Regexp.escape(wc).gsub('\*', '.*?')
return true if user.email =~ /^#{re_str}$/
end if wildcards
false
end
# Returns the service represented as a legacy hash
def as_legacy
def as_legacy(user)
# Synthesize tier info
tiers = {}
@ -68,6 +108,7 @@ class Service < ActiveRecord::Base
end
self.plans.each do |p|
next unless visible_to_user?(user, p)
tiers[p] = {
:options => {},
:order => sort_orders[p], # XXX - Sort order. Synthesized for now (alphabetical), may want to add support for this to svcs api.

Просмотреть файл

@ -143,6 +143,8 @@ builtin_services:
token: "0xdeadbeef"
filesystem:
token: "0xdeadbeef"
vblob:
token: "0xdeadbeef"
# Service broker
service_broker:

Просмотреть файл

@ -100,8 +100,8 @@ describe ServicesController do
it 'should update existing offerings' do
acls = {
'users' => ['foo@bar.com'],
'wildcards' => ['*@foo.com'],
'plans' => {'free' => {'users' => ['a@b.com']}}
}
svc = Service.create(
:label => 'foo-bar',
@ -129,8 +129,8 @@ describe ServicesController do
it 'should support reverting existing offerings to nil' do
acls = {
'users' => ['foo@bar.com'],
'wildcards' => ['*@foo.com'],
'plans' => {'free' => {'users' => ['aaa@bbb.com']}}
}
svc = Service.create(
:label => 'foo-bar',
@ -384,6 +384,7 @@ describe ServicesController do
svc.label = "foo-bar"
svc.url = "http://localhost:56789"
svc.token = 'foobar'
svc.plans = ['free', 'nonfree']
svc.save
svc.should be_valid
@svc = svc

Просмотреть файл

@ -74,8 +74,13 @@ describe Service do
@user_b.set_and_encrypt_password('foo')
@user_b.should be_valid
@user_c = User.new(:email => 'c@foo.com')
@user_c.set_and_encrypt_password('foo')
@user_c.should be_valid
@svc = make_service(
:url => 'http://www.foo.com',
:plans => ['plan_a', 'plan_b', 'plan_c'],
:label => 'foo-bar',
:token => 'foobar'
)
@ -83,6 +88,7 @@ describe Service do
@user_acl_svc = make_service(
:url => 'http://www.foo.com',
:plans => ['plan_a', 'plan_b', 'plan_c'],
:label => 'foo-bar1',
:token => 'foobar',
:acls => {'users' => ['a@bar.com'], 'wildcards' => []}
@ -91,14 +97,43 @@ describe Service do
@wc_acl_svc = make_service(
:url => 'http://www.foo.com',
:plans => ['plan_a', 'plan_b', 'plan_c'],
:label => 'foo-bar2',
:token => 'foobar',
:acls => {'users' => [], 'wildcards' => ['*@bar.com']}
)
@wc_acl_svc.should be_valid
@p_acl_svc = make_service(
:url => 'http://www.foo.com',
:plans => ['plan_a', 'plan_b', 'plan_c'],
:label => 'foo-bar3',
:token => 'foobar',
:acls => {
'plans' => {
'plan_a' => {'wildcards' => ['*@bar.com']}
}
}
)
@p_acl_svc.should be_valid
@combo_acl_svc = make_service(
:url => 'http://www.foo.com',
:plans => ['plan_a', 'plan_b', 'plan_c'],
:label => 'foo-bar4',
:token => 'foobar',
:acls => {
'wildcards' => ['*@bar.com'],
'plans' => {
'plan_a' => {'users' => ['a@bar.com']}
}
}
)
@combo_acl_svc.should be_valid
end
it "should return true for services with no acls" do
@svc.visible_to_user?(@user_a, 'plan_a').should be_true
@svc.visible_to_user?(@user_a).should be_true
end
@ -110,6 +145,27 @@ describe Service do
it "should correctly validate users in the wildcard acl" do
@wc_acl_svc.visible_to_user?(@user_a).should be_true
@wc_acl_svc.visible_to_user?(@user_b).should be_true
@wc_acl_svc.visible_to_user?(@user_c).should be_false
end
it "should correctly validate user in the plan acls" do
@p_acl_svc.visible_to_user?(@user_a).should be_true # can see plan_a, plan_b, plan_c
@p_acl_svc.visible_to_user?(@user_b).should be_true # can see plan_a, plan_b, plan_c
@p_acl_svc.visible_to_user?(@user_c).should be_true # can see plan_b, plan_c
@p_acl_svc.visible_to_user?(@user_a, "plan_a").should be_true
@p_acl_svc.visible_to_user?(@user_b, "plan_a").should be_true
@p_acl_svc.visible_to_user?(@user_c, "plan_a").should be_false
end
it "should correctly validate user in the service acls and the plan acls" do
@combo_acl_svc.visible_to_user?(@user_a).should be_true # can see plan_a, plan_b, plan_c
@combo_acl_svc.visible_to_user?(@user_b).should be_true # can see plan_b, plan_c
@combo_acl_svc.visible_to_user?(@user_c).should be_false # can not see service
@combo_acl_svc.visible_to_user?(@user_a, "plan_a").should be_true
@combo_acl_svc.visible_to_user?(@user_b, "plan_a").should be_false
@combo_acl_svc.visible_to_user?(@user_c, "plan_a").should be_false
end
end

Двоичные данные
cloud_controller/vendor/cache/vcap_common-1.0.10.gem поставляемый Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -1,7 +1,7 @@
PATH
remote: .
specs:
vcap_common (1.0.9)
vcap_common (1.0.10)
eventmachine (~> 0.12.11.cloudfoundry.3)
nats (~> 0.4.22.beta.8)
posix-spawn (~> 0.3.6)

Просмотреть файл

@ -26,14 +26,14 @@ module VCAP
optional :plans, [String]
optional :plan_options
optional :binding_options
optional :acls, {'users' => [String], 'wildcards' => [String]}
optional :acls
optional :active
optional :timeout, Integer
end
class BrokeredServiceOfferingRequest < JsonMessage
required :label, SERVICE_LABEL_REGEX
required :options, [{"name" => String, "acls" => {"users" => [String], "wildcards" => [String] } , "credentials" => Hash}]
required :options, [{"name" => String, "credentials" => Hash}]
optional :description, String
end

Просмотреть файл

@ -1,6 +1,6 @@
spec = Gem::Specification.new do |s|
s.name = 'vcap_common'
s.version = '1.0.9'
s.version = '1.0.10'
s.date = '2011-02-09'
s.summary = 'vcap common'
s.homepage = "http://github.com/vmware-ac/core"

Просмотреть файл

@ -23,7 +23,7 @@ default[:cloud_controller][:staging][:django] = "django.yml"
default[:cloud_controller][:staging][:wsgi] = "wsgi.yml"
# Default builtin services
default[:cloud_controller][:builtin_services] = ["redis", "mongodb", "mysql", "neo4j"]
default[:cloud_controller][:builtin_services] = ["redis", "mongodb", "mysql", "neo4j", "rabbitmq"]
# Default capacity
default[:capacity][:max_uris] = 4

Просмотреть файл

@ -13,5 +13,8 @@ define :cloudfoundry_service do
mode 0644
end
end
cf_bundle_install(File.expand_path(File.join(node[:cloudfoundry][:path], "services", params[:name])))
service_name = params[:name]
# Work around for RabbitMQ service since its directory name is "rabbit"
service_name = "rabbit" if service_name == "rabbitmq"
cf_bundle_install(File.expand_path(File.join(node[:cloudfoundry][:path], "services", service_name)))
end

Просмотреть файл

@ -29,7 +29,7 @@ bash "Install Erlang" do
code <<-EOH
tar xvzf otp_src_#{node[:erlang][:version]}.tar.gz
cd otp_src_#{node[:erlang][:version]}
#{File.join(".", "configure")} --prefix=#{node[:erlang][:path]}
#{File.join(".", "configure")} --prefix=#{node[:erlang][:path]} --disable-hipe
make
make install
EOH

Просмотреть файл

@ -10,7 +10,7 @@ pid: /var/vcap/sys/run/mongodb_node.pid
max_memory: <%= node[:mongodb_node][:max_memory] %>
node_id: <%= "mongodb_node_#{node[:mongodb_node][:index]}" %>
mongod_path: <%= File.join(node[:mongodb][:path], "bin", "mongod") %>
mongorestore_path: mongorestore
mongorestore_path: <%= File.join(node[:mongodb][:path], "bin", "mongorestore") %>
port_range:
first: 25001
last: 45000

Просмотреть файл

@ -1,8 +1,10 @@
include_attribute "deployment"
default[:neo4j][:version] = "community-1.4.1"
default[:neo4j][:distribution_file] = "neo4j-#{node[:neo4j][:version]}-unix.tar.gz"
default[:neo4j][:service_dir] = "/var/vcap/services/neo4j"
default[:neo4j][:hosting_extension] = "authentication-extension-1.4.jar"
default[:neo4j_node][:capacity] = "200"
default[:neo4j_node][:index] = "0"
default[:neo4j_node][:available_memory] = "4096"
default[:neo4j_node][:max_memory] = "128"

Просмотреть файл

@ -1,4 +1,6 @@
---
capacity: <%= node[:neo4j_node][:capacity] %>
plan: free
local_db: sqlite3:/var/vcap/services/neo4j/neo4j_node.db
mbus: nats://<%= node[:nats_server][:user] %>:<%= node[:nats_server][:password] %>@<%= node[:nats_server][:host] %>:<%= node[:nats_server][:port] %>/
index: <%= node[:neo4j_node][:index] %>

Просмотреть файл

@ -1,3 +1,10 @@
default[:rabbitmq][:version] = "2.4.0"
default[:rabbitmq][:version_full] = "2.4.0-1_all"
default[:rabbitmq][:source] = "http://www.rabbitmq.com/releases/rabbitmq-server/v#{rabbitmq[:version]}/rabbitmq-server_#{rabbitmq[:version_full]}.deb"
include_attribute "deployment"
default[:rabbitmq][:version] = "2.4.1"
default[:rabbitmq][:version_full] = "generic-unix-2.4.1"
default[:rabbitmq][:path] = File.join(node[:deployment][:home], "deploy", "rabbitmq")
default[:rabbitmq][:source] = "http://www.rabbitmq.com/releases/rabbitmq-server/v#{rabbitmq[:version]}/rabbitmq-server-#{rabbitmq[:version_full]}.tar.gz"
default[:rabbitmq][:plugins] = ["amqp_client", "mochiweb", "rabbitmq-management", "rabbitmq-management-agent", "rabbitmq-mochiweb", "webmachine"]
default[:rabbitmq][:plugins_source] = "http://www.rabbitmq.com/releases/plugins/v#{rabbitmq[:version]}/"
default[:rabbitmq_node][:index] = "0"
default[:rabbitmq_node][:token] = "changerabbitmqtoken"

Просмотреть файл

@ -10,18 +10,49 @@ case node['platform']
when "ubuntu"
package "erlang-nox"
remote_file File.join("", "tmp", "rabbitmq-server_#{node[:rabbitmq][:version_full]}.deb") do
remote_file File.join("", "tmp", "rabbitmq-server-#{node[:rabbitmq][:version_full]}.tar.gz") do
owner node[:deployment][:user]
source node[:rabbitmq][:source]
not_if { ::File.exists?(File.join("", "tmp", "rabbitmq-server_#{node[:rabbitmq][:version_full]}.deb")) }
not_if { ::File.exists?(File.join("", "tmp", "rabbitmq-server-#{node[:rabbitmq][:version_full]}.tar.gz")) }
end
node[:rabbitmq][:plugins].each do |plugin_name|
remote_file File.join("", "tmp", "#{plugin_name}-#{node[:rabbitmq][:version]}.ez") do
owner node[:deployment][:user]
source "#{node[:rabbitmq][:plugins_source]}#{plugin_name}-#{node[:rabbitmq][:version]}.ez"
not_if { ::File.exists?(File.join("", "tmp", "#{plugin_name}-#{node[:rabbitmq][:version]}.ez")) }
end
end
directory "#{node[:rabbitmq][:path]}" do
owner node[:deployment][:user]
group node[:deployment][:user]
mode "0755"
end
bash "Install RabbitMQ" do
cwd File.join("", "tmp")
user node[:deployment][:user]
code <<-EOH
dpkg -i rabbitmq-server_#{node[:rabbitmq][:version_full]}.deb
tar xzf rabbitmq-server-#{node[:rabbitmq][:version_full]}.tar.gz
cd rabbitmq_server-#{node[:rabbitmq][:version]}
cp -rf * #{node[:rabbitmq][:path]}
EOH
not_if do
::File.exists?(File.join("", "usr", "sbin", "rabbitmq-server"))
::File.exists?(File.join(node[:rabbitmq][:path], "sbin", "rabbitmq-server"))
end
end
node[:rabbitmq][:plugins].each do |plugin_name|
bash "Install RabbitMQ #{plugin_name} plugin" do
cwd File.join("", "tmp")
user node[:deployment][:user]
code <<-EOH
cp -f "#{plugin_name}-#{node[:rabbitmq][:version]}.ez" #{File.join(node[:rabbitmq][:path], "plugins")}
EOH
not_if do
::File.exists?(File.join(node[:rabbitmq][:path], "plugins", "#{plugin_name}-#{node[:rabbitmq][:version]}.ez"))
end
end
end
else

Просмотреть файл

@ -0,0 +1,10 @@
#
# Cookbook Name:: gateway
# Recipe:: default
#
# Copyright 2011, VMware
#
cloudfoundry_service "rabbitmq" do
components ["rabbitmq_gateway"]
end

Просмотреть файл

@ -0,0 +1,10 @@
#
# Cookbook Name:: node
# Recipe:: default
#
# Copyright 2011, VMware
#
cloudfoundry_service "rabbitmq" do
components ["rabbitmq_node"]
end

Просмотреть файл

@ -0,0 +1,23 @@
---
cloud_controller_uri: <%= node[:cloud_controller][:service_api_uri] %>
service:
name: rabbitmq
version: "2.4"
description: "RabbitMQ message queue"
plans: ["free"]
tags: ["rabbitmq", "rabitmq-2.4", "message-queue", "amqp"]
timeout: 15
host: localhost
index: 0
token: <%= node[:rabbitmq_node][:token] %>
mbus: nats://<%= node[:nats_server][:user] %>:<%= node[:nats_server][:password] %>@<%= node[:nats_server][:host] %>:<%= node[:nats_server][:port] %>/
pid: /var/vcap/sys/run/rabbit_gateway.pid
logging:
level: debug
plan_management:
plans:
free:
low_water: 10
high_water: 180
#allow_over_provisioning: false
node_timeout: 10

Просмотреть файл

@ -0,0 +1,22 @@
---
capacity: 100
plan: free
local_db: sqlite3:/var/vcap/services/rabbit/rabbit_node.db
base_dir: /var/vcap/services/rabbit/instances
mbus: nats://<%= node[:nats_server][:user] %>:<%= node[:nats_server][:password] %>@<%= node[:nats_server][:host] %>:<%= node[:nats_server][:port] %>/
index: <%= node[:rabbitmq_node][:index] %>
logging:
level: debug
pid: /var/vcap/sys/run/rabbit_node.pid
node_id: <%= "rabbit_node_free_#{node[:rabbitmq_node][:index]}" %>
migration_nfs: /mnt/vcap
port_range:
first: 10001
last: 20000
admin_port_range:
first: 20001
last: 30000
max_clients: 1000
rabbitmq_log_dir: /var/vcap/services/rabbit/logs
rabbitmq_server: <%= File.join(node[:rabbitmq][:path], "sbin", "rabbitmq-server") %>
rabbitmq_start_timeout: 5

Просмотреть файл

@ -20,7 +20,7 @@ class JobManager
ACM = "acm"
ACMDB = "acmdb"
SERVICES = ["redis", "mysql", "mongodb", "neo4j"]
SERVICES = ["redis", "mysql", "mongodb", "neo4j", "rabbitmq"]
SERVICES_NODE = SERVICES.map do |service|
"#{service}_node"
end
@ -39,7 +39,7 @@ class JobManager
# List of the required properties for jobs
INSTALLED_JOB_PROPERTIES = {NATS => ["host"], CC => ["service_api_uri", "builtin_services"],
CCDB => ["host"]}
INSTALL_JOB_PROPERTIES = {CC => ["builtin_services"], MYSQL_NODE => ["index"], MONGODB_NODE => ["index"], REDIS_NODE => ["index"], NEO4J_NODE => ["index"]}
INSTALL_JOB_PROPERTIES = {CC => ["builtin_services"], MYSQL_NODE => ["index"], MONGODB_NODE => ["index"], REDIS_NODE => ["index"], NEO4J_NODE => ["index"], RABBITMQ_NODE => ["index"]}
# Dependency between JOBS and components that are consumed by "vcap_dev" when cf is started or
# stopped

Просмотреть файл

@ -0,0 +1,11 @@
{
"name": "rabbitmq_gateway",
"override_attributes": {},
"json_class": "Chef::Role",
"description": "RabbitMQ services gateway",
"chef_type": "role",
"run_list" : [ "recipe[deployment]",
"recipe[essentials]",
"recipe[ruby]",
"recipe[rabbitmq::gateway]"]
}

Просмотреть файл

@ -0,0 +1,12 @@
{
"name": "redis_node",
"override_attributes": {},
"json_class": "Chef::Role",
"description": "RabbitMQ service node",
"chef_type": "role",
"run_list" : ["recipe[deployment]",
"recipe[essentials]",
"recipe[ruby]",
"recipe[rabbitmq]",
"recipe[rabbitmq::node]"]
}

Просмотреть файл

@ -9,7 +9,7 @@ module CoreComponents
end
def components
%w[cloud_controller dea health_manager router stager acm services/redis services/mysql services/mongodb services/postgresql services/neo4j]
%w[cloud_controller dea health_manager router stager acm services/redis services/mysql services/mongodb services/postgresql services/neo4j services/rabbit]
end
def dirs

@ -1 +1 @@
Subproject commit cd74fa64c11e9f275ad49fafa19939bd0b8c78e8
Subproject commit fb5fdf4c41828a6263faff04a467afb8987129d5