| # |
| # Licensed to the Apache Software Foundation (ASF) under one or more |
| # contributor license agreements. See the NOTICE file distributed with |
| # this work for additional information regarding copyright ownership. The |
| # ASF licenses this file to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance with the |
| # License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| # License for the specific language governing permissions and limitations |
| # under the License. |
| # |
| #Definition of CIMI methods for the mock driver - seperation from deltacloud |
| #API mock driver methods |
| |
| module Deltacloud::Drivers::Mock |
| |
| class MockDriver < Deltacloud::BaseDriver |
| |
| def systems(credentials, opts={}) |
| check_credentials(credentials) |
| if opts[:id].nil? |
| systems = @client.load_all_cimi(:system).map{|sys| CIMI::Model::System.from_json(sys)} |
| else |
| begin |
| systems = [CIMI::Model::System.from_json(@client.load_cimi(:system, opts[:id]))] |
| rescue Errno::ENOENT |
| return [] |
| end |
| end |
| systems.map{|sys| convert_urls(sys, opts[:env])}.flatten |
| systems |
| end |
| |
| def create_system(credentials, opts={}) |
| check_credentials(credentials) |
| create_system_components_for(opts[:name], opts[:system_template].component_descriptors, opts[:env]) |
| id = "#{opts[:env].send("systems_url")}/#{opts[:name]}" |
| sys_hsh = { "id"=> id, |
| "name" => opts[:name], |
| "description" => opts[:description], |
| "created" => Time.now, |
| "state" => "STARTED", |
| "operations" => [{"rel"=>"http://schemas.dmtf.org/cimi/1/action/stop", "href"=> "#{id}/stop"}, |
| {"rel"=>"edit", "href"=> id}, |
| {"rel"=>"delete", "href"=> id}]} |
| system = CIMI::Model::System.from_json(JSON.generate(sys_hsh)) |
| @client.store_cimi(:system, system) |
| system |
| end |
| |
| def create_system_components_for(system_id, component_descriptors, context) |
| component_descriptors.each do |cd| |
| cd_type = cd.type.split("/").last |
| model = CIMI::Model.const_get("#{cd_type}Create").new |
| #assign the template from the component descriptor |
| model.send("#{cd_type.underscore}_template=".to_sym, cd.send("#{cd_type.underscore}_template".to_sym)) |
| #also the name, description from the component descriptor for the new resource: |
| model.send(:name=, cd.name) |
| model.send(:description=, cd.description) |
| resource = CIMI::Service.const_get("#{cd_type}Create").new(context, :model=>model) |
| #create quantity number of resources, obeying naming rules |
| if cd.quantity && cd.quantity > 1 |
| cd.quantity.times do |t| |
| resource.model.send(:name=, "#{cd.name}#{t+1}") |
| created_sys_comp = resource.create.model |
| store_created_system_component(created_sys_comp, cd_type, system_id, context) |
| end |
| else |
| created_sys_comp = resource.create.model |
| store_created_system_component(created_sys_comp, cd_type, system_id, context) |
| end |
| end |
| end |
| |
| def store_created_system_component(component, type, system_id, context) |
| seq_id = generate_system_component_id(type.underscore) |
| id = "#{context.send("system_url")}/#{system_id}/#{type.pluralize.underscore}/#{seq_id}" |
| system_component_hash = { :id => id, |
| :name =>component.name, |
| :description =>component.description, |
| :created => Time.now, |
| "#{type.underscore}".to_sym => {:href => component.id}, |
| :operations=> [{"rel"=>"edit", "href"=> id}, |
| {"rel"=>"delete", "href"=> id}] |
| } |
| system_component = CIMI::Model.const_get("System#{type}").from_json(JSON.generate(system_component_hash)) |
| @client.store_cimi("system_#{type.underscore}".to_sym, system_component, seq_id) |
| end |
| |
| def generate_system_component_id(type) |
| ids = @client.cimi_members("system_#{type}".to_sym) |
| count, next_id = 1, '' |
| loop do |
| break unless ids.include?(next_id = "sys_#{type}_#{count}") |
| count = count + 1 |
| end |
| next_id |
| end |
| |
| def destroy_system(credentials, id) |
| check_credentials(credentials) |
| #retrieve the system_machines to delete them |
| sys_machines = system_machines(credentials, {:system_id => id}) |
| sys_machines.each do |mach| |
| inst_id = mach.machine.href.split("/").last |
| @client.destroy(:instances, inst_id) |
| mach_id = mach.id.split("/").last |
| @client.destroy_cimi(:system_machine, mach_id) |
| end |
| @client.destroy_cimi(:system, id) |
| end |
| |
| def start_system(credentials, id) |
| check_credentials(credentials) |
| sys_machines = system_machines(credentials, {:system_id => id}) |
| sys_machines.each do |mach| |
| inst_id = mach.machine.href.split("/").last |
| update_instance_state(credentials, inst_id , "RUNNING") #deltacloud instance, not machine |
| end |
| #retrieve system machines: |
| update_object_state(id, "System", "STARTED") |
| end |
| |
| def stop_system(credentials, id) |
| check_credentials(credentials) |
| sys_machines = system_machines(credentials, {:system_id => id}) |
| sys_machines.each do |mach| |
| inst_id = mach.machine.href.split("/").last |
| update_instance_state(credentials, inst_id , "STOPPED") |
| end |
| update_object_state(id, "System", "STOPPED") |
| end |
| |
| def import_system(credentials, opts={}) |
| puts "import_system(#{opts})" |
| end |
| |
| def export_system(credentials, opts={}) |
| puts "export_system(#{opts})" |
| "http://cimi.example.org/ovf-packages/#{opts[:id]}" unless opts[:destination] |
| end |
| |
| def system_machines(credentials, opts={}) |
| check_credentials(credentials) |
| if opts[:id].nil? |
| all_machines = @client.load_all_cimi(:system_machine).map{|mach| CIMI::Model::SystemMachine.from_json(mach)} |
| #grab only ones for system_id: |
| machines = all_machines.inject([]){|res,cur| res << cur if cur.id =~ /^.*\/systems\/#{opts[:system_id]}\/machines/ ;res} |
| else |
| begin |
| machines = [CIMI::Model::SystemMachine.from_json(@client.load_cimi(:system_machine, opts[:id]))] |
| rescue Errno::ENOENT |
| return [] |
| end |
| end |
| machines.map{|m|convert_urls(m, opts[:env])}.flatten |
| end |
| |
| def system_volumes(credentials, opts={}) |
| check_credentials(credentials) |
| if opts[:id].nil? |
| all_volumes = @client.load_all_cimi(:system_volume).map{|vol| CIMI::Model::SystemVolume.from_json(vol)} |
| volumes = all_volumes.inject([]){|res,cur| res << cur if cur.id =~ /^.*\/systems\/#{opts[:system_id]}\/volumes/ ;res} |
| else |
| begin |
| volumes = [CIMI::Model::SystemVolume.from_json(@client.load_cimi(:system_volume, opts[:id]))] |
| rescue Errno::ENOENT |
| return [] |
| end |
| end |
| volumes.map{|vol|convert_urls(vol, opts[:env])}.flatten |
| end |
| |
| def system_networks(credentials, opts={}) |
| check_credentials(credentials) |
| if opts[:id].nil? |
| networks = @client.load_all_cimi(:system_network).map{|net| CIMI::Model::SystemNetwork.from_json(net)} |
| else |
| begin |
| networks = [CIMI::Model::SystemNetwork.from_json(@client.load_cimi(:system_network, opts[:id]))] |
| rescue Errno::ENOENT |
| return [] |
| end |
| end |
| networks.map{|n|convert_urls(n, opts[:env])}.flatten |
| end |
| |
| def system_addresses(credentials, opts={}) |
| check_credentials(credentials) |
| if opts[:id].nil? |
| addresses = @client.load_all_cimi(:system_address).map{|a| CIMI::Model::SystemAddress.from_json(a)} |
| else |
| begin |
| addresses = [CIMI::Model::SystemVolume.from_json(@client.load_cimi(:system_address, opts[:id]))] |
| rescue Errno::ENOENT |
| return [] |
| end |
| end |
| addresses.map{|a|convert_urls(a, opts[:env])}.flatten |
| end |
| |
| def system_forwarding_groups(credentials, opts={}) |
| check_credentials(credentials) |
| if opts[:id].nil? |
| groups = @client.load_all_cimi(:system_forwarding_group).map{|group| CIMI::Model::SystemForwardingGroup.from_json(group)} |
| else |
| begin |
| groups = [CIMI::Model::SystemForwardingGroup.from_json(@client.load_cimi(:system_forwarding_group, opts[:id]))] |
| rescue Errno::ENOENT |
| return [] |
| end |
| end |
| groups.map{|g|convert_urls(g, opts[:env])}.flatten |
| end |
| |
| def system_templates(credentials, opts={}) |
| check_credentials(credentials) |
| if opts[:id].nil? |
| system_templates = @client.load_all_cimi(:system_template).map{|sys_templ| CIMI::Model::SystemTemplate.from_json(sys_templ)} |
| else |
| begin |
| system_templates = [CIMI::Model::SystemTemplate.from_json(@client.load_cimi(:system_template, opts[:id]))] |
| rescue Errno::ENOENT |
| return [] |
| end |
| end |
| system_templates.map{|sys_templ| convert_urls(sys_templ, opts[:env])}.flatten |
| end |
| |
| def import_system_template (credentials, opts={}) |
| puts "import_system(#{opts})" |
| end |
| |
| def export_system_template(credentials, opts={}) |
| puts "export_system(#{opts})" |
| "http://cimi.example.org/ovf-packages/#{opts[:id]}" unless opts[:destination] |
| end |
| |
| def networks(credentials, opts={}) |
| check_credentials(credentials) |
| if opts[:id].nil? |
| networks = @client.load_all_cimi(:network).map{|net| CIMI::Model::Network.from_json(net)} |
| networks.map{|net| convert_urls(net, opts[:env])}.flatten |
| else |
| network = CIMI::Model::Network.from_json(@client.load_cimi(:network, opts[:id])) |
| convert_urls(network, opts[:env]) |
| end |
| end |
| |
| def create_network(credentials, opts={}) |
| check_credentials(credentials) |
| id = "#{opts[:env].send("networks_url")}/#{opts[:name]}" |
| net_hsh = { "id"=> id, |
| "name" => opts[:name], |
| "description" => opts[:description], |
| "created" => Time.now, |
| "state" => "STARTED", |
| "networkType" => opts[:network_config].network_type, |
| "mtu" => opts[:network_config].mtu, |
| "classOfService" => opts[:network_config].class_of_service, |
| |
| |
| "forwardingGroup"=> { "href" => opts[:forwarding_group].id }, |
| "operations" => [{"rel"=>"edit", "href"=> id}, |
| {"rel"=>"delete", "href"=> id}] } |
| network = CIMI::Model::Network.from_json(JSON.generate(net_hsh)) |
| |
| @client.store_cimi(:network, network) |
| network |
| end |
| |
| def delete_network(credentials, id) |
| check_credentials(credentials) |
| @client.destroy_cimi(:network, id) |
| end |
| |
| def start_network(credentials, id) |
| check_credentials(credentials) |
| update_object_state(id, "Network", "STARTED") |
| end |
| |
| def stop_network(credentials, id) |
| check_credentials(credentials) |
| update_object_state(id, "Network", "STOPPED") |
| end |
| |
| def suspend_network(credentials, id) |
| check_credentials(credentials) |
| update_object_state(id, "Network", "SUSPENDED") |
| end |
| |
| def network_configurations(credentials, opts={}) |
| check_credentials(credentials) |
| if opts[:id].nil? |
| network_configs = @client.load_all_cimi(:network_configuration).map{|net_config| CIMI::Model::NetworkConfiguration.from_json(net_config)} |
| network_configs.map{|net_config| convert_urls(net_config, opts[:env])}.flatten |
| else |
| network_config = CIMI::Model::NetworkConfiguration.from_json(@client.load_cimi(:network_configuration, opts[:id])) |
| convert_urls(network_config, opts[:env]) |
| end |
| end |
| |
| def network_templates(credentials, opts={}) |
| check_credentials(credentials) |
| if opts[:id].nil? |
| network_templates = @client.load_all_cimi(:network_template).map{|net_templ| CIMI::Model::NetworkTemplate.from_json(net_templ)} |
| network_templates.map{|net_templ| convert_urls(net_templ, opts[:env])}.flatten |
| else |
| network_template = CIMI::Model::NetworkTemplate.from_json(@client.load_cimi(:network_template, opts[:id])) |
| convert_urls(network_template, opts[:env]) |
| end |
| end |
| |
| def forwarding_group_templates(credentials, opts={}) |
| check_credentials(credentials) |
| if opts[:id].nil? |
| forwarding_group_templates = @client.load_all_cimi(:forwarding_group_template).map{|fg_templ| CIMI::Model::ForwardingGroupTemplate.from_json(fg_templ)} |
| forwarding_group_templates.map{|fg_templ| convert_urls(fg_templ, opts[:env])}.flatten |
| else |
| forwarding_group_template = CIMI::Model::ForwardingGroupTemplate.from_json(@client.load_cimi(:forwarding_group_template, opts[:id])) |
| convert_urls(forwarding_group_template, opts[:env]) |
| end |
| end |
| |
| def network_ports(credentials, opts={}) |
| check_credentials(credentials) |
| if opts[:id].nil? |
| ports = @client.load_all_cimi(:network_port).map{|net_port| CIMI::Model::NetworkPort.from_json(net_port)} |
| ports.map{|net_port| convert_urls(net_port, opts[:env])}.flatten |
| else |
| port = CIMI::Model::NetworkPort.from_json(@client.load_cimi(:network_port, opts[:id])) |
| convert_urls(port, opts[:env]) |
| end |
| end |
| |
| def network_port_configurations(credentials, opts={}) |
| check_credentials(credentials) |
| if opts[:id].nil? |
| network_port_configurations = @client.load_all_cimi(:network_port_configuration).map{|network_port_config| CIMI::Model::NetworkPortConfiguration.from_json(network_port_config)} |
| network_port_configurations.map{|network_port_config| convert_urls(network_port_config, opts[:env])}.flatten |
| else |
| network_port_configuration = CIMI::Model::NetworkPortConfiguration.from_json(@client.load_cimi(:network_port_configuration, opts[:id])) |
| convert_urls(network_port_configuration, opts[:env]) |
| end |
| end |
| |
| def network_port_templates(credentials, opts={}) |
| check_credentials(credentials) |
| if opts[:id].nil? |
| network_port_templates = @client.load_all_cimi(:network_port_template).map{|net_port_templ| CIMI::Model::NetworkPortTemplate.from_json(net_port_templ)} |
| network_port_templates.map{|net_port_templ| convert_urls(net_port_templ, opts[:env])}.flatten |
| else |
| network_port_template = CIMI::Model::NetworkPortTemplate.from_json(@client.load_cimi(:network_port_template, opts[:id])) |
| convert_urls(network_port_template, opts[:env]) |
| end |
| end |
| |
| def address_templates(credentials, opts={}) |
| check_credentials(credentials) |
| if opts[:id].nil? |
| address_templates = @client.load_all_cimi(:address_template).map{|addr_templ| CIMI::Model::AddressTemplate.from_json(addr_templ)} |
| address_templates.map{|addr_templ| convert_urls(addr_templ, opts[:env])}.flatten |
| else |
| address_template = CIMI::Model::AddressTemplate.from_json(@client.load_cimi(:address_template, opts[:id])) |
| convert_urls(address_template, opts[:env]) |
| end |
| end |
| |
| private |
| |
| # Convert all attributes that have values of the form |
| # http://cimi.example.org/COLL/ID |
| # or |
| # http://cimi.example.org/COLL/ID/SUBCOLL/ENT_ID |
| def convert_urls(val, context) |
| if val.nil? || val.is_a?(Fixnum) |
| # Nothing to do |
| elsif val.is_a?(Struct) |
| val.members.each { |m| val[m] = convert_urls(val[m], context) } |
| elsif val.is_a?(Hash) |
| val.keys.each { |m| val[m] = convert_urls(val[m], context) } |
| elsif val.is_a?(Array) |
| val.each_index { |i| val[i] = convert_urls(val[i], context) } |
| elsif val.is_a?(String) |
| val = rewrite_url(val, context) |
| elsif val.is_a?(CIMI::Model::Resource) |
| val.attribute_values.each do |k, v| |
| val[k] = convert_urls(val[k], context) |
| end |
| else |
| # Need to add a branch for val.class |
| raise "Whoa ! #{val.inspect}" |
| end |
| val |
| end |
| |
| # Rewrite URL assuming it points at a valid resource; if that's not |
| # possible, return +s+ |
| # |
| # URLs that should be rewritten need to be in the form |
| # http://cimi.example.org/COLLECTION/ID |
| # or |
| # http://cimi.example.org/COLLECTION/SYSTEM_ID/SUBCOLLECTION/ENT_ID |
| def rewrite_url(s, context) |
| begin |
| u = URI.parse(s) |
| rescue URI::InvalidURIError |
| return s |
| end |
| return s unless u.scheme == 'http' && u.host == 'cimi.example.org' |
| _, coll, id, sub_coll, sub_id = u.path.split("/") |
| method = sub_coll ? "#{coll.singularize}_#{sub_coll.singularize}_url" |
| : "#{coll.singularize}_url" |
| if context.respond_to?(method) |
| sub_coll ? context.send(method, :id => id, :ent_id => sub_id) |
| : context.send(method, id) |
| else |
| s |
| end |
| end |
| |
| def update_object_state(id, object, new_state) |
| klass = CIMI::Model.const_get("#{object}") |
| symbol = object.to_s.downcase.singularize.intern |
| obj = klass.from_json(@client.load_cimi(symbol, id)) |
| obj.state = new_state |
| @client.store_cimi(symbol, obj) |
| obj |
| end |
| |
| end |
| |
| end |