1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-02-03 13:47:01 +03:00

Merge branch 'feature-1125'

This commit is contained in:
Ruben S. Montero 2012-05-07 17:35:18 +02:00
commit 74158cf206
17 changed files with 260 additions and 191 deletions

View File

@ -157,9 +157,9 @@ class VDCHelper < OZonesHelper::OZHelper
puts str % ["CLUSTER_ID ", vdc[:CLUSTER_ID].to_s]
puts str % ["GROUP_ID ", vdc[:GROUP_ID].to_s]
puts str % ["VDCADMIN ", vdc[:VDCADMINNAME].to_s]
puts str % ["HOSTS ", vdc[:RESOURCES][:HOSTS].to_s]
puts str % ["DATASTORES ", vdc[:RESOURCES][:DATASTORES].to_s]
puts str % ["NETWORKS ", vdc[:RESOURCES][:NETWORKS].to_s]
puts str % ["HOSTS ", vdc[:RESOURCES][:HOSTS].join(',')]
puts str % ["DATASTORES ", vdc[:RESOURCES][:DATASTORES].join(',')]
puts str % ["NETWORKS ", vdc[:RESOURCES][:NETWORKS].join(',')]
puts
return 0

View File

@ -44,6 +44,8 @@ class ZonesHelper < OZonesHelper::OZHelper
puts str % ["ZONE ADMIN ",zone[:ONENAME].to_s]
puts str % ["ZONE PASS ", zone[:ONEPASS].to_s]
puts str % ["ENDPOINT ", zone[:ENDPOINT].to_s]
puts str % ["SUNSENDPOINT ", zone[:SUNSENDPOINT].to_s]
puts str % ["SELFENDPOINT ", zone[:SELFENDPOINT].to_s]
puts str % ["# VDCS ", zone[:VDCS].size.to_s]
puts

View File

@ -34,26 +34,24 @@ module OZones
zone_pool_hash = zone.to_hash["ZONE"]
client = OpenNebula::Client.new("#{zone.ONENAME}:#{zone.ONEPASS}",
zone.ENDPOINT)
client = OpenNebula::Client.new("#{zone.ONENAME}:#{zone.ONEPASS}",
zone.ENDPOINT)
pool = factory(client)
if OpenNebula.is_error?(pool)
zone_pool_hash.merge!(pool.to_hash)
next
end
rc = pool.info
if !rc
zone_pool_hash.merge!(pool.to_hash)
elsif OpenNebula.is_error?(rc)
error = "Error communicating with #{zone.NAME}."
error << " Retrieving #{self.class.name.split('::').last}: "
error << "#{rc.to_str}"
zone_pool_hash.merge!({:error => {:message => error}})
else
zone_pool_hash.merge!(rc.to_hash)
end
@sup_aggregated_pool[@tag]["ZONE"] << zone_pool_hash
}
end

View File

@ -24,8 +24,8 @@ module OZones
def update
htaccess = "RewriteEngine On\n"
OZones::Zones.all.each{|zone|
zone.vdcs.all.each{|vdc|
OZones::Zones.each{|zone|
zone.vdcs.each{|vdc|
htaccess << "RewriteRule ^#{vdc.NAME} " +
"#{zone.ENDPOINT} [P]\n"

View File

@ -22,20 +22,34 @@ module OZones
# ID, NAME, the GROUP backing the VDC, the admin credentials and the VDC
# resources. VDC resources are stored in JSON document in the DB and used as
# a hash in the VDC.
class Vdc
include DataMapper::Resource
class Vdc < Sequel::Model
include OpenNebulaJSON::JSONUtils
extend OpenNebulaJSON::JSONUtils
property :ID, Serial
property :NAME, String, :required => true, :unique => true
property :GROUP_ID, Integer
property :VDCADMINNAME, String, :required => true
property :VDCADMIN_ID, Integer
property :CLUSTER_ID, Integer
property :RESOURCES, Text
plugin :schema
plugin :validation_helpers
belongs_to :zones
set_schema do
primary_key :ID
String :NAME, :unique => true
Integer :GROUP_ID
foreign_key :ZONES_ID, :zones, :key => :ID
String :VDCADMINNAME
Integer :VDCADMIN_ID
Integer :CLUSTER_ID
String :RESOURCES, :text => true
end
create_table unless table_exists?
many_to_one :zone, :class => 'OZones::Zones', :key => :ZONES_ID
def validate
super
validates_presence [:NAME, :VDCADMINNAME]
validates_unique :NAME
end
def resources
rsrc_json = self.RESOURCES
@ -55,11 +69,7 @@ module OZones
zonePoolHash["VDC_POOL"]["VDC"] = Array.new unless self.all.empty?
self.all.each{ |vdc|
# Hack! zones_ID does not respect the "all capital letters" policy
attrs = vdc.attributes.clone
attrs[:ZONES_ID] = vdc.attributes[:zones_ID]
attrs.delete(:zones_ID)
attrs = vdc.values.clone
rsrc_json = attrs.delete(:RESOURCES)
parser = JSON.parser.new(rsrc_json, {:symbolize_names=>true})
@ -74,11 +84,7 @@ module OZones
def to_hash
vdc_attributes = Hash.new
# Hack! zones_ID does not respect the "all capital letters" policy
attrs = attributes.clone
attrs[:ZONES_ID] = attributes[:zones_ID]
attrs.delete(:zones_ID)
attrs = @values.clone
rsrc_json = attrs.delete(:RESOURCES)
parser = JSON.parser.new(rsrc_json, {:symbolize_names=>true})
@ -111,13 +117,13 @@ module OZones
#Creates an OpenNebula VDC, using its ID, vdcid and the associated zone
def initialize(vdcid, zone = nil)
if vdcid != -1
@vdc = Vdc.get(vdcid)
@vdc = Vdc[vdcid]
if !@vdc
raise "VDC with id #{vdcid} not found."
end
@zone = OZones::Zones.get(@vdc.zones_ID)
@zone = OZones::Zones[@vdc.ZONES_ID]
else
@zone = zone
end
@ -150,9 +156,17 @@ module OZones
#-------------------------------------------------------------------
# Create a vdc record & check cluster consistency
#-------------------------------------------------------------------
@vdc = Vdc.new
begin
@vdc.attributes = vdc_data
@vdc = Vdc.new
@vdc.update(vdc_data)
@vdc.ZONES_ID = @zone.ID
rescue => e
return OpenNebula::Error.new(e.message)
end
rc = resources_in_cluster?(rsrc)
@ -202,6 +216,7 @@ module OZones
rsrc[:ACLS] = acl_ids
@vdc.resources = rsrc
@vdc.save
return true
end
@ -283,10 +298,8 @@ module OZones
#Update the VDC Record
# ------------------------------------------------------------------
begin
@vdc.raise_on_save_failure = true
@vdc.resources = rsrc_hash
@vdc.save
@vdc.save(:raise_on_failure => true)
rescue => e
return OpenNebula::Error.new(e.message)
end

View File

@ -16,29 +16,42 @@
module OZones
class Zones
include DataMapper::Resource
class Zones < Sequel::Model
include OpenNebulaJSON::JSONUtils
extend OpenNebulaJSON::JSONUtils
plugin :schema
plugin :validation_helpers
#######################################################################
# Data Model for the Zone
#######################################################################
property :ID, Serial
property :NAME, String, :required => true, :unique => true
property :ONENAME, String, :required => true
property :ONEPASS, String, :required => true
property :ENDPOINT, String, :required => true
property :SUNSENDPOINT, String
property :SELFENDPOINT, String
set_schema do
primary_key :ID
String :NAME, :unique => true
String :ONENAME
String :ONEPASS
String :ENDPOINT
String :SUNSENDPOINT
String :SELFENDPOINT
end
has n, :vdcs
create_table unless table_exists?
one_to_many :vdcs, :class => 'OZones::Vdc', :key => :ZONES_ID
#######################################################################
# Constants
#######################################################################
ZONE_ATTRS = [:ONENAME, :ONEPASS, :ENDPOINT, :NAME]
def validate
super
validates_presence ZONE_ATTRS
validates_unique :NAME
end
#######################################################################
# JSON Functions
#######################################################################
@ -47,11 +60,11 @@ module OZones
zonePoolHash["ZONE_POOL"] = Hash.new
zonePoolHash["ZONE_POOL"]["ZONE"] = Array.new unless self.all.empty?
self.all.each{|zone|
zattr = zone.attributes.clone
self.each{|zone|
zattr = zone.values.clone
zattr[:ONEPASS] = Zones.encrypt(zattr[:ONEPASS])
zattr[:NUMBERVDCS] = zone.vdcs.all.size
zattr[:NUMBERVDCS] = zone.vdcs.size
zonePoolHash["ZONE_POOL"]["ZONE"] << zattr
}
@ -62,12 +75,12 @@ module OZones
def to_hash
zattr = Hash.new
zattr["ZONE"] = attributes.clone
zattr["ZONE"] = @values.clone
zattr["ZONE"][:ONEPASS] = Zones.encrypt(zattr["ZONE"][:ONEPASS])
zattr["ZONE"][:VDCS] = Array.new
self.vdcs.all.each{|vdc|
zattr["ZONE"][:VDCS]<< vdc.attributes.clone
self.vdcs.each{|vdc|
zattr["ZONE"][:VDCS]<< vdc.values.clone
}
return zattr
@ -111,10 +124,7 @@ module OZones
# Create the zone
begin
zone = Zones.new
zone.raise_on_save_failure = true
zone.attributes = zone_data
zone.save
zone.update(zone_data)
rescue => e
return OZones::Error.new(e.message)
end
@ -165,7 +175,7 @@ module OZones
##########################################################################
class OpenNebulaZone
def initialize(zoneid)
@zone = Zones.get(zoneid)
@zone = Zones[zoneid]
if !@zone
raise "Error: Zone with id #{zoneid} not found"
@ -199,7 +209,13 @@ module OZones
return [404, error.to_json]
end
pool.info
rc = pool.info
if OpenNebula.is_error?(rc)
error = "Error communicating with #{@zone.NAME}."
error << " Retrieving #{pool_kind} pool: "
error << "#{rc.to_str}"
return [500, OZones::Error.new(error).to_json]
end
return [200, pool.to_json]
end

View File

@ -14,12 +14,21 @@
# limitations under the License. #
#--------------------------------------------------------------------------- #
class Auth
class Auth < Sequel::Model
plugin :schema
plugin :validation_helpers
include DataMapper::Resource
set_schema do
primary_key :id
String :name, :unique => true
String :password
end
property :id, Serial
property :name, String, :required => true, :unique => true
property :password, String, :required => true
create_table unless table_exists?
def validate
super
validates_unique(:name)
validates_presence [:name, :password]
end
end

View File

@ -36,7 +36,7 @@ class OzonesServer < CloudServer
# Gets a VDC
def get_vdc(id)
vdc = OZones::Vdc.get(id)
vdc = OZones::Vdc[id]
if vdc
return [200, vdc.to_json]
@ -53,7 +53,7 @@ class OzonesServer < CloudServer
#Gets a zone
def get_zone(id)
zone = OZones::Zones.get(id)
zone = OZones::Zones[id]
if zone
return [200, zone.to_json]
@ -101,7 +101,7 @@ class OzonesServer < CloudServer
"Mandatory attribute zoneid missing.").to_json]
end
zone = OZones::Zones.get(zoneid)
zone = OZones::Zones[zoneid]
if !zone
return [404, OZones::Error.new("Error: Couldn't create vdc. " \
"Zone #{zoneid} not found.").to_json]
@ -126,11 +126,10 @@ class OzonesServer < CloudServer
#-----------------------------------------------------------------------
#Update the zone and save the vdc
#-----------------------------------------------------------------------
zone.raise_on_save_failure = true
zone.vdcs << vdc.vdc
begin
zone.save
zone.save(:raise_on_failture => true)
rescue => e
#vdc.clean_bootstrap
logger.error {"create_vdc: #{e.resource.errors.inspect}"}
@ -231,7 +230,7 @@ class OzonesServer < CloudServer
end
def delete_zone(id, pr)
zone = OZones::Zones.get(id)
zone = OZones::Zones[id]
if zone
rc = zone.destroy
@ -264,7 +263,7 @@ class OzonesServer < CloudServer
all_hosts = Array.new
zone.vdcs.all(:CLUSTER_ID =>c_id).each{ |vdc|
zone.vdcs(:CLUSTER_ID =>c_id).each{ |vdc|
rsrc = vdc.resources
if !rsrc[:HOSTS].empty? and vdc.ID != vdc_data[:ID]

View File

@ -51,7 +51,7 @@ require 'sinatra'
require 'yaml'
require 'rubygems'
require 'data_mapper'
require 'sequel'
require 'digest/sha1'
require 'OzonesServer'
@ -102,18 +102,16 @@ enable_logging OZONES_LOG, settings.config[:debug_level].to_i
##############################################################################
# DB bootstrapping
##############################################################################
if config[:dbdebug]
DataMapper::Logger.new($stdout, :debug)
end
DataMapper.setup(:default, db_url)
DB = Sequel.connect(db_url)
if config[:dbdebug]
DB.loggers << settings.logger
end
require 'OZones'
require 'Auth'
DataMapper.finalize
DataMapper.auto_upgrade!
if Auth.all.size == 0
if ENV['OZONES_AUTH'] && File.exist?(ENV['OZONES_AUTH'])
credentials = IO.read(ENV['OZONES_AUTH']).strip.split(':')
@ -123,9 +121,10 @@ if Auth.all.size == 0
exit -1
end
credentials[1] = Digest::SHA1.hexdigest(credentials[1])
@auth=Auth.create({:name => credentials[0],
:password => credentials[1]})
@auth.save
@auth=Auth.new
@auth.name = credentials[0]
@auth.password = credentials[1]
@auth.save(:raise_on_failure => true)
else
error_m = "oZones admin credentials not set, missing OZONES_AUTH file."
settings.logger.error { error_m }

View File

@ -2,13 +2,9 @@
"VDC_POOL": {
"VDC": [
{
"NAME": "vdcA",
"VDCADMINNAME": "vdcadminA",
"VDCADMIN_ID": 2,
"ID": 1,
"RESOURCES": {
"DATASTORES": [
100
],
"HOSTS": [
0,
1,
@ -27,21 +23,21 @@
8,
9,
10
]
},
"GROUP_ID": 100,
"ZONES_ID": 1,
"VDCADMINNAME": "vdcadminA",
"CLUSTER_ID": 100
},
{
"NAME": "vdcB",
"VDCADMIN_ID": 2,
"ID": 2,
"RESOURCES": {
],
"DATASTORES": [
100
],
]
},
"NAME": "vdcA",
"CLUSTER_ID": 100,
"ZONES_ID": 1,
"ID": 1,
"GROUP_ID": 100
},
{
"VDCADMINNAME": "vdcadminB",
"VDCADMIN_ID": 2,
"RESOURCES": {
"HOSTS": [
1
],
@ -56,21 +52,21 @@
6,
7,
8
]
},
"GROUP_ID": 100,
"ZONES_ID": 2,
"VDCADMINNAME": "vdcadminB",
"CLUSTER_ID": 100
},
{
"NAME": "vdcC",
"VDCADMIN_ID": 3,
"ID": 3,
"RESOURCES": {
],
"DATASTORES": [
100
],
]
},
"NAME": "vdcB",
"CLUSTER_ID": 100,
"ZONES_ID": 2,
"ID": 2,
"GROUP_ID": 100
},
{
"VDCADMINNAME": "vdcadminC",
"VDCADMIN_ID": 3,
"RESOURCES": {
"HOSTS": [
3
],
@ -85,12 +81,16 @@
15,
16,
17
],
"DATASTORES": [
100
]
},
"GROUP_ID": 101,
"NAME": "vdcC",
"CLUSTER_ID": 100,
"ZONES_ID": 1,
"VDCADMINNAME": "vdcadminC",
"CLUSTER_ID": 100
"ID": 3,
"GROUP_ID": 101
}
]
}

View File

@ -2,13 +2,9 @@
"VDC_POOL": {
"VDC": [
{
"NAME": "vdcA",
"VDCADMINNAME": "vdcadminA",
"VDCADMIN_ID": 2,
"ID": 1,
"RESOURCES": {
"DATASTORES": [
100
],
"HOSTS": [
0,
1,
@ -27,21 +23,21 @@
8,
9,
10
]
},
"GROUP_ID": 100,
"ZONES_ID": 1,
"VDCADMINNAME": "vdcadminA",
"CLUSTER_ID": 100
},
{
"NAME": "vdcB",
"VDCADMIN_ID": 2,
"ID": 2,
"RESOURCES": {
],
"DATASTORES": [
100
],
]
},
"NAME": "vdcA",
"CLUSTER_ID": 100,
"ZONES_ID": 1,
"ID": 1,
"GROUP_ID": 100
},
{
"VDCADMINNAME": "vdcadminB",
"VDCADMIN_ID": 2,
"RESOURCES": {
"HOSTS": [
1
],
@ -56,12 +52,16 @@
6,
7,
8
],
"DATASTORES": [
100
]
},
"GROUP_ID": 100,
"NAME": "vdcB",
"CLUSTER_ID": 100,
"ZONES_ID": 2,
"VDCADMINNAME": "vdcadminB",
"CLUSTER_ID": 100
"ID": 2,
"GROUP_ID": 100
}
]
}

View File

@ -2,24 +2,24 @@
"ZONE_POOL": {
"ZONE": [
{
"NAME": "zoneA",
"SUNSENDPOINT": "http://localhost:9869",
"SELFENDPOINT": null,
"ONENAME": "oneadminA",
"ID": 1,
"ONEPASS": "OkqWM2aSqbM/nlrdHGv3OA==",
"ENDPOINT": "http://localhost:2666/RPC2",
"NUMBERVDCS": 0
"SUNSENDPOINT": "http://localhost:9869",
"NAME": "zoneA",
"SELFENDPOINT": null,
"NUMBERVDCS": 0,
"ID": 1,
"ONENAME": "oneadminA",
"ONEPASS": "e/TkohQckqFcmcWFwrirUapdiLkg87GHPafKnxkzznk="
},
{
"NAME": "zoneB",
"SUNSENDPOINT": null,
"SELFENDPOINT": null,
"ONENAME": "oneadminB",
"ID": 2,
"ONEPASS": "8Si8vlo2P3qn5/SNxkMkDg==",
"ENDPOINT": "http://localhost:2667/RPC2",
"NUMBERVDCS": 0
"SUNSENDPOINT": null,
"NAME": "zoneB",
"SELFENDPOINT": null,
"NUMBERVDCS": 0,
"ID": 2,
"ONENAME": "oneadminB",
"ONEPASS": "DrnuZMnmOFVeYTXTVwTgEmOGw2orTjaU/f1NyuNKlQY="
}
]
}

View File

@ -2,14 +2,14 @@
"ZONE_POOL": {
"ZONE": [
{
"NAME": "zoneA",
"SUNSENDPOINT": "http://localhost:9869",
"SELFENDPOINT": null,
"ONENAME": "oneadminA",
"ID": 1,
"ONEPASS": "OkqWM2aSqbM/nlrdHGv3OA==",
"ENDPOINT": "http://localhost:2666/RPC2",
"NUMBERVDCS": 0
"SUNSENDPOINT": "http://localhost:9869",
"NAME": "zoneA",
"SELFENDPOINT": null,
"NUMBERVDCS": 0,
"ID": 1,
"ONENAME": "oneadminA",
"ONEPASS": "e/TkohQckqFcmcWFwrirUapdiLkg87GHPafKnxkzznk="
}
]
}

View File

@ -1,12 +1,8 @@
{
"VDC": {
"NAME": "vdcA",
"VDCADMINNAME": "vdcadminA",
"VDCADMIN_ID": 2,
"ID": 1,
"RESOURCES": {
"DATASTORES": [
100
],
"HOSTS": [
0,
1,
@ -25,11 +21,15 @@
8,
9,
10
],
"DATASTORES": [
100
]
},
"GROUP_ID": 100,
"NAME": "vdcA",
"CLUSTER_ID": 100,
"ZONES_ID": 1,
"VDCADMINNAME": "vdcadminA",
"CLUSTER_ID": 100
"ID": 1,
"GROUP_ID": 100
}
}

View File

@ -1,14 +1,14 @@
{
"ZONE": {
"NAME": "zoneA",
"ENDPOINT": "http://localhost:2666/RPC2",
"SUNSENDPOINT": "http://localhost:9869",
"NAME": "zoneA",
"SELFENDPOINT": null,
"ID": 1,
"ONENAME": "oneadminA",
"VDCS": [
],
"SELFENDPOINT": null,
"ONENAME": "oneadminA",
"ID": 1,
"ONEPASS": "OkqWM2aSqbM/nlrdHGv3OA==",
"ENDPOINT": "http://localhost:2666/RPC2"
"ONEPASS": "e/TkohQckqFcmcWFwrirUapdiLkg87GHPafKnxkzznk="
}
}

View File

@ -154,13 +154,25 @@ module OZones
it "should be able to retrieve the vdc pool" do
vdcpool = @vdchelper.list_pool({:json => true})
vdcpool[0].should eql(0)
vdcpool[1].should eql(File.read(TESTS_PATH+"examples/pool/vdcpool0.json"))
got = vdcpool[1]
expected = File.read(TESTS_PATH+"examples/pool/vdcpool0.json")
got = JSON.parser.new(got, {:symbolize_names => true}).parse
expected = JSON.parser.new(expected, {:symbolize_names => true}).parse
got.should eql(expected)
end
it "should be able to retrieve a particular vdc" do
vdc = @vdchelper.show_resource(1, {:json => true})
vdc[0].should eql(0)
vdc[1].should eql(File.read(TESTS_PATH+"examples/vdc/vdc0.json"))
got = vdc[1]
expected = File.read(TESTS_PATH+"examples/vdc/vdc0.json")
got = JSON.parser.new(got, {:symbolize_names => true}).parse
expected = JSON.parser.new(expected, {:symbolize_names => true}).parse
got.should eql(expected)
end
it "should allow deleting a vdc" do
@ -168,8 +180,13 @@ module OZones
rc[0].should eql(0)
rc = @vdchelper.list_pool({:json => true})
rc[0].should eql(0)
rc[1].should eql(File.read(TESTS_PATH+
"examples/pool/vdcpool_deleted.json"))
got = rc[1]
expected = File.read(TESTS_PATH+"examples/pool/vdcpool_deleted.json")
got = JSON.parser.new(got, {:symbolize_names => true}).parse
expected = JSON.parser.new(expected, {:symbolize_names => true}).parse
got.should eql(expected)
end
it "should fail on non-existing vdc deletion" do

View File

@ -72,14 +72,25 @@ module OZones
it "should be able to retrieve the zone pool" do
zonepool = @helper.list_pool({:json => true})
zonepool[0].should eql(0)
zonepool[1].should eql(File.read(TESTS_PATH+
"examples/pool/zonepool0.json"))
got = zonepool[1]
expected = File.read(TESTS_PATH+"examples/pool/zonepool0.json")
got = JSON.parser.new(got, {:symbolize_names => true}).parse
expected = JSON.parser.new(expected, {:symbolize_names => true}).parse
got.should eql(expected)
end
it "should be able to retrieve a particular zone" do
zone = @helper.show_resource(1,{:json => true})
zone[0].should eql(0)
zone[1].should eql(File.read(TESTS_PATH+"examples/zone/zone0.json"))
got = zone[1]
expected = File.read(TESTS_PATH+"examples/zone/zone0.json")
got = JSON.parser.new(got, {:symbolize_names => true}).parse
expected = JSON.parser.new(expected, {:symbolize_names => true}).parse
got.should eql(expected)
end
it "should allow deleting a zone" do
@ -87,8 +98,13 @@ module OZones
rc[0].should eql(0)
rc = @helper.list_pool({:json => true})
rc[0].should eql(0)
rc[1].should eql(File.read(TESTS_PATH+
"examples/pool/zonepool_deleted.json"))
got = rc[1]
expected = File.read(TESTS_PATH+"examples/pool/zonepool_deleted.json")
got = JSON.parser.new(got, {:symbolize_names => true}).parse
expected = JSON.parser.new(expected, {:symbolize_names => true}).parse
got.should eql(expected)
end
it "should fail on non existing zone deletion" do