From: marios <[email protected]> List, create, delete key for Openstack Driver. Relies on https://github.com/ruby-openstack/ruby-openstack/pull/2
Adds 'import_key' feature for creating new Key in Keys collection (supported by openstack, feature "import_key") Updated .gemspec to use new openstack gem (>=1.0.1) for keys Signed-off-by: marios <[email protected]> --- server/deltacloud-core.gemspec | 2 +- server/lib/deltacloud/collections/buckets.rb | 2 +- server/lib/deltacloud/collections/instances.rb | 1 + server/lib/deltacloud/collections/keys.rb | 6 ++- server/lib/deltacloud/drivers/features.rb | 8 +++ .../drivers/openstack/openstack_driver.rb | 47 +++++++++++++++++++- server/views/keys/new.html.haml | 11 ++++- 7 files changed, 71 insertions(+), 6 deletions(-) diff --git a/server/deltacloud-core.gemspec b/server/deltacloud-core.gemspec index c69aed5..e5c7119 100644 --- a/server/deltacloud-core.gemspec +++ b/server/deltacloud-core.gemspec @@ -101,6 +101,6 @@ Gem::Specification.new do |s| s.add_dependency('uuidtools', '>= 2.1.1') # Openstack Compute and Object-Storage - s.add_dependency('openstack') + s.add_dependency('openstack', '>= 1.0.1') end diff --git a/server/lib/deltacloud/collections/buckets.rb b/server/lib/deltacloud/collections/buckets.rb index 3282535..28b6d5a 100644 --- a/server/lib/deltacloud/collections/buckets.rb +++ b/server/lib/deltacloud/collections/buckets.rb @@ -48,7 +48,7 @@ module Deltacloud::Collections end end - put route_for ("/buckets/:bucket/:blob") do + put route_for("/buckets/:bucket/:blob") do if(env["BLOB_SUCCESS"]) #ie got a 200ok after putting blob content_type = env["CONTENT_TYPE"] content_type ||= "" diff --git a/server/lib/deltacloud/collections/instances.rb b/server/lib/deltacloud/collections/instances.rb index 933ecaf..0faea0c 100644 --- a/server/lib/deltacloud/collections/instances.rb +++ b/server/lib/deltacloud/collections/instances.rb @@ -47,6 +47,7 @@ module Deltacloud::Collections param :image_id, :string, :required param :realm_id, :string, :optional param :hwp_id, :string, :optional + param :keyname, :string, :optional control do @instance = driver.create_instance(credentials, params[:image_id], params) if @instance.kind_of? Array diff --git a/server/lib/deltacloud/collections/keys.rb b/server/lib/deltacloud/collections/keys.rb index 55d0fa8..6d0ef03 100644 --- a/server/lib/deltacloud/collections/keys.rb +++ b/server/lib/deltacloud/collections/keys.rb @@ -15,6 +15,9 @@ module Deltacloud::Collections class Keys < Base + + include Deltacloud::Features + check_capability :for => lambda { |m| driver.respond_to? m } check_features :for => lambda { |c, f| driver.class.has_feature?(c, f) } @@ -31,8 +34,9 @@ module Deltacloud::Collections operation :create, :with_capability => :create_key do param :name, :string, :required + param :public_key, :string, :optional control do - @key = driver.create_key(credentials, { :key_name => params[:name] }) + @key = driver.create_key(credentials, { :key_name => params[:name], :public_key => params[:public_key]}) status 201 response['Location'] = key_url(@key.id) respond_to do |format| diff --git a/server/lib/deltacloud/drivers/features.rb b/server/lib/deltacloud/drivers/features.rb index 7e98749..bc8bb5b 100644 --- a/server/lib/deltacloud/drivers/features.rb +++ b/server/lib/deltacloud/drivers/features.rb @@ -148,6 +148,14 @@ module Deltacloud param :sandbox, :string, :optional end end + + feature :import_key, :for => :keys do + description "Allow importing existing public key for creation of new key on provider" + operation :create do + param :public_key, :string, :optional + end + end + end end diff --git a/server/lib/deltacloud/drivers/openstack/openstack_driver.rb b/server/lib/deltacloud/drivers/openstack/openstack_driver.rb index 91624f5..b7b7c65 100644 --- a/server/lib/deltacloud/drivers/openstack/openstack_driver.rb +++ b/server/lib/deltacloud/drivers/openstack/openstack_driver.rb @@ -23,9 +23,11 @@ module Deltacloud class OpenstackDriver < Deltacloud::BaseDriver feature :instances, :user_name + feature :instances, :authentication_key feature :instances, :authentication_password feature :instances, :user_files feature :images, :user_name + feature :keys, :import_key define_instance_states do start.to( :pending ) .on( :create ) @@ -142,6 +144,9 @@ module Deltacloud if opts[:password] && opts[:password].length > 0 params[:adminPass]=opts[:password] end + if opts[:keyname] && opts[:keyname].length > 0 + params[:key_name]=opts[:keyname] + end safely do server = os.create_server(params) result = convert_from_server(server, os.connection.authuser) @@ -285,6 +290,30 @@ module Deltacloud return http, request end + def keys(credentials, opts={}) + os = new_client(credentials) + keys = [] + safely do + os.keypairs.values.each{|key| keys << convert_key(key)} + end + filter_on(keys, :id, opts) + end + + def create_key(credentials, opts={}) + os = new_client(credentials) + safely do + params = (opts[:public_key] and opts[:public_key].length > 0)? {:name=>opts[:key_name], :public_key=> opts[:public_key]} : {:name=>opts[:key_name]} + convert_key(os.create_keypair(params)) + end + end + + def destroy_key(credentials, opts={}) + os = new_client(credentials) + safely do + os.delete_keypair(opts[:id]) + end + end + private #for v2 authentication credentials.name == "username+tenant_name" @@ -362,7 +391,8 @@ private :public_addresses => convert_server_addresses(server, :public), :private_addresses => convert_server_addresses(server, :private), :username => 'root', - :password => password + :password => password, + :keyname => server.send(op, :key_name) ) inst.actions = instance_actions_for(inst.state) inst.create_image = 'RUNNING'.eql?(inst.state) @@ -411,6 +441,17 @@ private :user_metadata => blob_meta }) end + def convert_key(key) + Key.new( + :id => key[:name], + :fingerprint => key[:fingerprint], + :credential_type => :key, + :pem_rsa_key => key[:private_key], # only available once, on create_key + :state => "AVAILABLE" + ) + end + + #IN: path1='server_path1'. content1='contents1', path2='server_path2', content2='contents2' etc #OUT:{local_path=>server_path, local_path1=>server_path2 etc} def extract_personality(opts) @@ -457,6 +498,10 @@ private status 500 end + on /OpenStack::Exception::NotImplemented/ do + status 501 + end + end diff --git a/server/views/keys/new.html.haml b/server/views/keys/new.html.haml index 4244f0a..8bb4ee2 100644 --- a/server/views/keys/new.html.haml +++ b/server/views/keys/new.html.haml @@ -3,6 +3,13 @@ %div{ :'data-role' => :content, :'data-theme' => 'c', :class => 'middle-dialog'} %form{ :action => keys_url, :method => :post} %div{ 'data-role' => :fieldcontain } - %label{ :for => :name} Key name: - %input{ :type => :text, :id => :name, :name => :name, :value => '' } + %p + %label{ :for => :name} Key name: + %p + %input{ :type => :text, :id => :name, :name => :name, :value => '' } + %p + %label{ :for => :public_key} Public Key (Optional - import): + %small Enter your public key here to import it rather than creating a new one (not supported by all providers) + %p + %textarea{ :name => :public_key, :cols=>65, :rows=>5 } %button{ :type => :submit} Create key -- 1.7.6.5
