foreman_digitalocean 0.2.1 → 1.0.0
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.
- checksums.yaml +4 -4
- data/app/helpers/digitalocean_images_helper.rb +33 -0
- data/app/models/concerns/fog_extensions/digitalocean/image.rb +5 -2
- data/app/models/concerns/fog_extensions/digitalocean/server.rb +6 -0
- data/app/models/foreman_digitalocean/concerns/host_managed_extensions.rb +16 -0
- data/app/models/foreman_digitalocean/digitalocean.rb +25 -29
- data/app/views/compute_resources/form/_digitalocean.html.erb +10 -7
- data/app/views/compute_resources_vms/form/digitalocean/_base.html.erb +7 -12
- data/app/views/compute_resources_vms/index/_digitalocean.html.erb +3 -3
- data/app/views/images/form/_digitalocean.html.erb +5 -2
- data/lib/foreman_digitalocean/engine.rb +27 -11
- data/lib/foreman_digitalocean/tasks/test.rake +44 -0
- data/lib/foreman_digitalocean/version.rb +1 -1
- data/test/factories/compute_resources.rb +13 -0
- data/test/test_plugin_helper.rb +6 -0
- data/test/unit/foreman_digitalocean/digitalocean_test.rb +18 -0
- metadata +12 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 09968431a3ccdbbd31a0dde996cfff6358a2a254
|
4
|
+
data.tar.gz: d044e4f386bd33594bcab16953e3380f2e334de7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 83c7f182dfabf192159f2c2678f9aafceaece54ba60f9d9a19d397456d54c6c969a588242b25df274b5e349e3dd21bd77dff86324c867a9df36e06715ca94a7d
|
7
|
+
data.tar.gz: 9a861c05403d615412a39530860cca00cc2193bd921aaee5ea9d63dd2b34fd2315e5208ab46d78685720a30b8803b3289a0258bb658dc38cd0af7d12bf336f8a
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module DigitaloceanImagesHelper
|
2
|
+
def digitalocean_image_field(f)
|
3
|
+
images = @compute_resource.available_images
|
4
|
+
images.each { |image| image.name = image.id if image.name.nil? }
|
5
|
+
select_f f, :uuid, images.to_a.sort_by(&:full_name),
|
6
|
+
:id, :full_name, {}, :label => _('Image')
|
7
|
+
end
|
8
|
+
|
9
|
+
def select_image(f, compute_resource)
|
10
|
+
images = possible_images(compute_resource, nil, nil)
|
11
|
+
|
12
|
+
select_f(f,
|
13
|
+
:image_id,
|
14
|
+
images,
|
15
|
+
:id,
|
16
|
+
:slug,
|
17
|
+
{ :include_blank => (images.empty? || images.size == 1) ? false : _('Please select an image') },
|
18
|
+
{ :label => ('Image'), :disabled => images.empty? } )
|
19
|
+
end
|
20
|
+
|
21
|
+
def select_region(f, compute_resource)
|
22
|
+
regions = compute_resource.regions
|
23
|
+
f.object.region = compute_resource.region
|
24
|
+
select_f(f,
|
25
|
+
:region,
|
26
|
+
regions,
|
27
|
+
:slug,
|
28
|
+
:slug,
|
29
|
+
{},
|
30
|
+
:label => ('Region'),
|
31
|
+
:disabled => compute_resource.images.empty?)
|
32
|
+
end
|
33
|
+
end
|
@@ -23,9 +23,12 @@ module FogExtensions
|
|
23
23
|
# Attempt guessing arch based on the name from digital ocean
|
24
24
|
def arch
|
25
25
|
requires :os_version
|
26
|
-
os_version.end_with?("x64")
|
26
|
+
if os_version.end_with?("x64")
|
27
|
+
"x86_64"
|
28
|
+
elsif os_version.end_with?("x32")
|
29
|
+
"i386"
|
30
|
+
end
|
27
31
|
end
|
28
|
-
|
29
32
|
end
|
30
33
|
end
|
31
34
|
end
|
@@ -3,6 +3,8 @@ module FogExtensions
|
|
3
3
|
module Server
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
|
+
attr_accessor :image_id
|
7
|
+
|
6
8
|
def identity_to_s
|
7
9
|
identity.to_s
|
8
10
|
end
|
@@ -44,6 +46,10 @@ module FogExtensions
|
|
44
46
|
[public_ip_address, private_ip_address].flatten.select(&:present?)
|
45
47
|
end
|
46
48
|
|
49
|
+
def state
|
50
|
+
requires :status
|
51
|
+
@state ||= status
|
52
|
+
end
|
47
53
|
end
|
48
54
|
end
|
49
55
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module ForemanDigitalocean
|
2
|
+
module Concerns
|
3
|
+
module HostManagedExtensions
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
# Rails 4 does not provide dynamic finders for delegated methods and
|
8
|
+
# the SSH orchestrate compute method uses them.
|
9
|
+
def self.find_by_ip(ip)
|
10
|
+
nic = Nic::Base.find_by_ip(ip)
|
11
|
+
nic.host if nic.present?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -1,24 +1,25 @@
|
|
1
1
|
module ForemanDigitalocean
|
2
2
|
class Digitalocean < ComputeResource
|
3
|
+
alias_attribute :api_key, :password
|
4
|
+
alias_attribute :region, :url
|
5
|
+
|
3
6
|
has_one :key_pair, :foreign_key => :compute_resource_id, :dependent => :destroy
|
4
7
|
delegate :flavors, :to => :client
|
5
8
|
|
6
|
-
validates :
|
9
|
+
validates :api_key, :presence => true
|
7
10
|
before_create :test_connection
|
8
11
|
|
9
12
|
after_create :setup_key_pair
|
10
13
|
after_destroy :destroy_key_pair
|
11
14
|
|
12
|
-
|
13
|
-
# Not sure why it would need a url, but OK (copied from ec2)
|
14
|
-
alias_attribute :region, :url
|
15
|
+
attr_accessible :region, :api_key
|
15
16
|
|
16
17
|
def to_label
|
17
18
|
"#{name} (#{provider_friendly_name})"
|
18
19
|
end
|
19
20
|
|
20
21
|
def provided_attributes
|
21
|
-
super.merge(
|
22
|
+
super.merge(:uuid => :identity_to_s, :ip => :public_ip_address)
|
22
23
|
end
|
23
24
|
|
24
25
|
def self.model_name
|
@@ -35,8 +36,9 @@ module ForemanDigitalocean
|
|
35
36
|
raise(ActiveRecord::RecordNotFound)
|
36
37
|
end
|
37
38
|
|
38
|
-
def create_vm(args = {
|
39
|
+
def create_vm(args = {})
|
39
40
|
args["ssh_keys"] = [ssh_key] if ssh_key
|
41
|
+
args['image'] = args['image_id']
|
40
42
|
super(args)
|
41
43
|
rescue Fog::Errors::Error => e
|
42
44
|
logger.error "Unhandled DigitalOcean error: #{e.class}:#{e.message}\n " + e.backtrace.join("\n ")
|
@@ -48,13 +50,13 @@ module ForemanDigitalocean
|
|
48
50
|
end
|
49
51
|
|
50
52
|
def regions
|
51
|
-
return [] if
|
53
|
+
return [] if api_key.blank?
|
52
54
|
client.regions
|
53
55
|
end
|
54
56
|
|
55
57
|
def test_connection(options = {})
|
56
58
|
super
|
57
|
-
errors[:
|
59
|
+
errors[:password].empty? && regions.count
|
58
60
|
rescue Excon::Errors::Unauthorized => e
|
59
61
|
errors[:base] << e.response.body
|
60
62
|
rescue Fog::Errors::Error => e
|
@@ -63,12 +65,12 @@ module ForemanDigitalocean
|
|
63
65
|
|
64
66
|
def destroy_vm(uuid)
|
65
67
|
vm = find_vm_by_uuid(uuid)
|
66
|
-
vm.
|
68
|
+
vm.delete if vm.present?
|
67
69
|
true
|
68
70
|
end
|
69
71
|
|
70
72
|
# not supporting update at the moment
|
71
|
-
def update_required?(
|
73
|
+
def update_required?(*)
|
72
74
|
false
|
73
75
|
end
|
74
76
|
|
@@ -77,7 +79,8 @@ module ForemanDigitalocean
|
|
77
79
|
end
|
78
80
|
|
79
81
|
def associated_host(vm)
|
80
|
-
Host.authorized(:view_hosts, Host).
|
82
|
+
Host.authorized(:view_hosts, Host).
|
83
|
+
where(:ip => [vm.public_ip_address, vm.private_ip_address]).first
|
81
84
|
end
|
82
85
|
|
83
86
|
def user_data_supported?
|
@@ -85,7 +88,7 @@ module ForemanDigitalocean
|
|
85
88
|
end
|
86
89
|
|
87
90
|
def default_region_name
|
88
|
-
@default_region_name ||= client.regions
|
91
|
+
@default_region_name ||= client.regions[region.to_i].try(:name)
|
89
92
|
rescue Excon::Errors::Unauthorized => e
|
90
93
|
errors[:base] << e.response.body
|
91
94
|
end
|
@@ -95,25 +98,24 @@ module ForemanDigitalocean
|
|
95
98
|
def client
|
96
99
|
@client ||= Fog::Compute.new(
|
97
100
|
:provider => "DigitalOcean",
|
98
|
-
:
|
99
|
-
:
|
101
|
+
:version => 'V2',
|
102
|
+
:digitalocean_token => api_key
|
100
103
|
)
|
101
104
|
end
|
102
105
|
|
103
106
|
def vm_instance_defaults
|
104
107
|
super.merge(
|
105
|
-
:
|
108
|
+
:size => client.flavors.first.slug
|
106
109
|
)
|
107
110
|
end
|
108
111
|
|
109
|
-
|
110
|
-
#
|
111
|
-
# it should create the key and upload it to DigitalOcean
|
112
|
+
# Creates a new key pair for each new DigitalOcean compute resource
|
113
|
+
# After creating the key, it uploads it to DigitalOcean
|
112
114
|
def setup_key_pair
|
113
115
|
public_key, private_key = generate_key
|
114
116
|
key_name = "foreman-#{id}#{Foreman.uuid}"
|
115
|
-
|
116
|
-
KeyPair.create! :name => key_name, :compute_resource_id =>
|
117
|
+
client.create_ssh_key key_name, public_key
|
118
|
+
KeyPair.create! :name => key_name, :compute_resource_id => id, :secret => private_key
|
117
119
|
rescue => e
|
118
120
|
logger.warn "failed to generate key pair"
|
119
121
|
logger.error e.message
|
@@ -134,24 +136,18 @@ module ForemanDigitalocean
|
|
134
136
|
|
135
137
|
def ssh_key
|
136
138
|
@ssh_key ||= begin
|
137
|
-
key = client.list_ssh_keys.data[:body]["ssh_keys"].
|
138
|
-
if key
|
139
|
-
#the vm creator expects objects which respond to id, OpenStruct is the shortest solution.
|
140
|
-
OpenStruct.new(key)
|
141
|
-
else
|
142
|
-
nil
|
143
|
-
end
|
139
|
+
key = client.list_ssh_keys.data[:body]["ssh_keys"].find { |i| i["name"] == key_pair.name }
|
140
|
+
key['id'] if key.present?
|
144
141
|
end
|
145
142
|
end
|
146
143
|
|
147
144
|
def generate_key
|
148
145
|
key = OpenSSL::PKey::RSA.new 2048
|
149
146
|
type = key.ssh_type
|
150
|
-
data = [
|
147
|
+
data = [key.to_blob].pack('m0')
|
151
148
|
|
152
149
|
openssh_format_public_key = "#{type} #{data}"
|
153
150
|
[openssh_format_public_key, key.to_pem]
|
154
151
|
end
|
155
|
-
|
156
152
|
end
|
157
153
|
end
|
@@ -1,11 +1,14 @@
|
|
1
|
-
<%=
|
2
|
-
<%= password_f f, :password, :label => _("API Key") %>
|
3
|
-
|
1
|
+
<%= password_f f, :api_key, :label => _("API Key"), :unset => unset_password? %>
|
4
2
|
<% regions = f.object.regions rescue [] %>
|
5
3
|
|
6
4
|
<div id='region_selection'>
|
7
|
-
<%= select_f(
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
<%= select_f(
|
6
|
+
f, :region, regions, :slug, :name, {},
|
7
|
+
:label => _('Default Region'), :disabled => regions.empty?,
|
8
|
+
:help_inline => link_to_function(
|
9
|
+
regions.empty? ? _("Load Regions") : _("Test Connection"), "testConnection(this)",
|
10
|
+
:class => "btn + #{regions.empty? ? "btn-default" : "btn-success"}",
|
11
|
+
:'data-url' => test_connection_compute_resources_path) +
|
12
|
+
spinner('', :id => 'test_connection_indicator',
|
13
|
+
:class => 'hide').html_safe) %>
|
11
14
|
</div>
|
@@ -1,12 +1,7 @@
|
|
1
|
-
<%= select_f f, :
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
f.object.region_id = compute_resource.region
|
9
|
-
%>
|
10
|
-
|
11
|
-
<div id='image_selection'><%= select_f f, :image_id, images, :uuid, :name, { :include_blank => (images.empty? || images.size == 1) ? false : _('Please Select an Image') }, { :label => ('Image'), :disabled => images.empty? } %></div>
|
12
|
-
<div id='region_selection'><%= select_f f, :region_id, regions, :id, :name, {}, { :label => ('Region'), :disabled => images.empty?} %></div>
|
1
|
+
<%= select_f f, :size, compute_resource.flavors, :slug, :slug, {}, {:label => _('Flavor')} %>
|
2
|
+
<div id='image_selection'>
|
3
|
+
<%= select_image(f, compute_resource) %>
|
4
|
+
</div>
|
5
|
+
<div id='region_selection'>
|
6
|
+
<%= select_region(f, compute_resource) %>
|
7
|
+
</div>
|
@@ -12,9 +12,9 @@
|
|
12
12
|
<% @vms.each do |vm| %>
|
13
13
|
<tr>
|
14
14
|
<td><%= link_to_if_authorized vm.name, hash_for_compute_resource_vm_path(:compute_resource_id => @compute_resource, :id => vm.identity).merge(:auth_object => @compute_resource, :authorizer => authorizer) %></td>
|
15
|
-
<td><%= vm.image
|
16
|
-
<td><%= vm.
|
17
|
-
<td><%= vm.region
|
15
|
+
<td><%= vm.image['slug'] if vm.image.present? %></td>
|
16
|
+
<td><%= vm.size['slug'] %></td>
|
17
|
+
<td><%= vm.region['slug'] %></td>
|
18
18
|
<td> <span <%= vm_power_class(vm.ready?) %>> <%= vm_state(vm) %></span> </td>
|
19
19
|
<td>
|
20
20
|
<%= action_buttons(
|
@@ -1,3 +1,6 @@
|
|
1
|
-
<%= text_f f,
|
2
|
-
|
1
|
+
<%= text_f f,
|
2
|
+
:username,
|
3
|
+
:value => @image.username || "root",
|
4
|
+
:help_inline => _("The user that is used to ssh into the instance, normally cloud-user, ec2-user, ubuntu, root etc") %>
|
5
|
+
<%= digitalocean_image_field(f) %>
|
3
6
|
<%= checkbox_f f, :user_data, :help_inline => _("Does this image support user data input (e.g. via cloud-init)?") %>
|
@@ -2,11 +2,11 @@ require 'fast_gettext'
|
|
2
2
|
require 'gettext_i18n_rails'
|
3
3
|
|
4
4
|
module ForemanDigitalocean
|
5
|
-
# Inherit from the Rails module of the parent app (Foreman), not the plugin.
|
6
|
-
# Thus, inherits from ::Rails::Engine and not from Rails::Engine
|
7
5
|
class Engine < ::Rails::Engine
|
8
6
|
engine_name 'foreman_digitalocean'
|
9
7
|
|
8
|
+
config.autoload_paths += Dir["#{config.root}/app/models/concerns"]
|
9
|
+
|
10
10
|
initializer 'foreman_digitalocean.register_gettext', :after => :load_config_initializers do
|
11
11
|
locale_dir = File.join(File.expand_path('../../..', __FILE__), 'locale')
|
12
12
|
locale_domain = 'foreman_digitalocean'
|
@@ -14,19 +14,35 @@ module ForemanDigitalocean
|
|
14
14
|
Foreman::Gettext::Support.add_text_domain locale_domain, locale_dir
|
15
15
|
end
|
16
16
|
|
17
|
-
initializer 'foreman_digitalocean.register_plugin', :
|
17
|
+
initializer 'foreman_digitalocean.register_plugin', :before => :finisher_hook do
|
18
18
|
Foreman::Plugin.register :foreman_digitalocean do
|
19
19
|
requires_foreman '>= 1.8'
|
20
20
|
compute_resource ForemanDigitalocean::Digitalocean
|
21
21
|
end
|
22
22
|
end
|
23
|
-
end
|
24
23
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
24
|
+
rake_tasks do
|
25
|
+
load "#{ForemanDigitalocean::Engine.root}/lib/foreman_digitalocean/tasks/test.rake"
|
26
|
+
end
|
27
|
+
|
28
|
+
config.to_prepare do
|
29
|
+
require 'fog/digitalocean'
|
30
|
+
require 'fog/digitalocean/compute_v2'
|
31
|
+
require 'fog/digitalocean/models/compute_v2/image'
|
32
|
+
require 'fog/digitalocean/models/compute_v2/server'
|
33
|
+
require File.expand_path(
|
34
|
+
'../../../app/models/concerns/fog_extensions/digitalocean/server',
|
35
|
+
__FILE__)
|
36
|
+
require File.expand_path(
|
37
|
+
'../../../app/models/concerns/fog_extensions/digitalocean/image',
|
38
|
+
__FILE__)
|
39
|
+
|
40
|
+
Fog::Compute::DigitalOceanV2::Image.send :include,
|
41
|
+
FogExtensions::DigitalOcean::Image
|
42
|
+
Fog::Compute::DigitalOceanV2::Server.send :include,
|
43
|
+
FogExtensions::DigitalOcean::Server
|
44
|
+
::Host::Managed.send :include,
|
45
|
+
ForemanDigitalocean::Concerns::HostManagedExtensions
|
46
|
+
end
|
47
|
+
end
|
32
48
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require File.expand_path("../engine", File.dirname(__FILE__))
|
2
|
+
namespace :test do
|
3
|
+
desc "Run the plugin unit test suite."
|
4
|
+
task :digitalocean => ['db:test:prepare'] do
|
5
|
+
test_task = Rake::TestTask.new('digitalocean_test_task') do |t|
|
6
|
+
t.libs << ["test", "#{ForemanDigitalocean::Engine.root}/test"]
|
7
|
+
t.test_files = [
|
8
|
+
"#{ForemanDigitalocean::Engine.root}/test/**/*_test.rb"
|
9
|
+
]
|
10
|
+
t.verbose = true
|
11
|
+
end
|
12
|
+
|
13
|
+
Rake::Task[test_task.name].invoke
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
namespace :digitalocean do
|
18
|
+
task :rubocop do
|
19
|
+
begin
|
20
|
+
require 'rubocop/rake_task'
|
21
|
+
RuboCop::RakeTask.new(:rubocop_digitalocean) do |task|
|
22
|
+
task.patterns = ["#{ForemanDigitalocean::Engine.root}/app/**/*.rb",
|
23
|
+
"#{ForemanDigitalocean::Engine.root}/lib/**/*.rb",
|
24
|
+
"#{ForemanDigitalocean::Engine.root}/test/**/*.rb"]
|
25
|
+
end
|
26
|
+
rescue
|
27
|
+
puts "Rubocop not loaded."
|
28
|
+
end
|
29
|
+
|
30
|
+
Rake::Task['rubocop_digitalocean'].invoke
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
Rake::Task[:test].enhance do
|
35
|
+
Rake::Task['test:digitalocean'].invoke
|
36
|
+
end
|
37
|
+
|
38
|
+
load 'tasks/jenkins.rake'
|
39
|
+
if Rake::Task.task_defined?(:'jenkins:unit')
|
40
|
+
Rake::Task["jenkins:unit"].enhance do
|
41
|
+
Rake::Task['test:digitalocean'].invoke
|
42
|
+
Rake::Task['digitalocean:rubocop'].invoke
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
FactoryGirl.define do
|
2
|
+
factory :container_resource, :class => ComputeResource do
|
3
|
+
sequence(:name) { |n| "compute_resource#{n}" }
|
4
|
+
|
5
|
+
trait :digitalocean do
|
6
|
+
provider 'Digitalocean'
|
7
|
+
api_key 'asampleapikey'
|
8
|
+
region 'everywhere'
|
9
|
+
end
|
10
|
+
|
11
|
+
factory :digitalocean_cr, :class => ForemanDigitalocean::Digitalocean, :traits => [:digitalocean]
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'test_plugin_helper'
|
2
|
+
|
3
|
+
class ForemanDigitalocean::DigitaloceanTest < ActiveSupport::TestCase
|
4
|
+
should validate_presence_of(:api_key)
|
5
|
+
should allow_mass_assignment_of(:region)
|
6
|
+
should allow_mass_assignment_of(:api_key)
|
7
|
+
should delegate_method(:flavors).to(:client)
|
8
|
+
should have_one(:key_pair)
|
9
|
+
|
10
|
+
setup { Fog.mock! }
|
11
|
+
teardown { Fog.unmock! }
|
12
|
+
|
13
|
+
test 'ssh key pair gets created after its saved' do
|
14
|
+
digitalocean = FactoryGirl.build(:digitalocean_cr)
|
15
|
+
digitalocean.expects(:setup_key_pair)
|
16
|
+
digitalocean.save
|
17
|
+
end
|
18
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman_digitalocean
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tommy McNeely, Daniel Lobato
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-04-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|
@@ -33,8 +33,10 @@ extra_rdoc_files: []
|
|
33
33
|
files:
|
34
34
|
- LICENSE
|
35
35
|
- README.md
|
36
|
+
- app/helpers/digitalocean_images_helper.rb
|
36
37
|
- app/models/concerns/fog_extensions/digitalocean/image.rb
|
37
38
|
- app/models/concerns/fog_extensions/digitalocean/server.rb
|
39
|
+
- app/models/foreman_digitalocean/concerns/host_managed_extensions.rb
|
38
40
|
- app/models/foreman_digitalocean/digitalocean.rb
|
39
41
|
- app/views/api/v1/compute_resources/digitalocean.json
|
40
42
|
- app/views/api/v2/compute_resources/digitalocean.json
|
@@ -46,8 +48,12 @@ files:
|
|
46
48
|
- app/views/images/form/_digitalocean.html.erb
|
47
49
|
- lib/foreman_digitalocean.rb
|
48
50
|
- lib/foreman_digitalocean/engine.rb
|
51
|
+
- lib/foreman_digitalocean/tasks/test.rake
|
49
52
|
- lib/foreman_digitalocean/version.rb
|
50
53
|
- locale/Makefile
|
54
|
+
- test/factories/compute_resources.rb
|
55
|
+
- test/test_plugin_helper.rb
|
56
|
+
- test/unit/foreman_digitalocean/digitalocean_test.rb
|
51
57
|
homepage: http://github.com/theforeman/foreman-digitalocean
|
52
58
|
licenses:
|
53
59
|
- GPL-3
|
@@ -72,4 +78,7 @@ rubygems_version: 2.2.2
|
|
72
78
|
signing_key:
|
73
79
|
specification_version: 4
|
74
80
|
summary: Provision and manage DigitalOcean droplets from Foreman
|
75
|
-
test_files:
|
81
|
+
test_files:
|
82
|
+
- test/factories/compute_resources.rb
|
83
|
+
- test/test_plugin_helper.rb
|
84
|
+
- test/unit/foreman_digitalocean/digitalocean_test.rb
|