foreman_snapshot_management 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -0
  3. data/Rakefile +0 -0
  4. data/app/controllers/api/v2/snapshots_controller.rb +107 -0
  5. data/app/controllers/concerns/foreman/controller/parameters/snapshot.rb +15 -0
  6. data/app/controllers/foreman_snapshot_management/snapshots_controller.rb +72 -54
  7. data/app/models/concerns/fog_extensions/vsphere/snapshots/mock.rb +33 -0
  8. data/app/models/concerns/fog_extensions/vsphere/snapshots/real.rb +43 -0
  9. data/app/models/foreman_snapshot_management/snapshot.rb +80 -22
  10. data/app/models/foreman_snapshot_management/vmware_extensions.rb +38 -6
  11. data/app/overrides/hosts/add_tab_to_host_overview.rb +2 -12
  12. data/app/views/api/v2/snapshots/base.json.rabl +3 -0
  13. data/app/views/api/v2/snapshots/create.json.rabl +3 -0
  14. data/app/views/api/v2/snapshots/destroy.json.rabl +3 -0
  15. data/app/views/api/v2/snapshots/index.json.rabl +3 -0
  16. data/app/views/api/v2/snapshots/main.json.rabl +9 -0
  17. data/app/views/api/v2/snapshots/revert.json.rabl +3 -0
  18. data/app/views/api/v2/snapshots/show.json.rabl +3 -0
  19. data/app/views/api/v2/snapshots/update.json.rabl +3 -0
  20. data/app/views/foreman_snapshot_management/hosts/_snapshots_tab.html.erb +3 -0
  21. data/app/views/foreman_snapshot_management/hosts/_snapshots_tab_content.html.erb +7 -0
  22. data/app/views/foreman_snapshot_management/snapshots/_index.html.erb +27 -16
  23. data/config/routes.rb +17 -0
  24. data/lib/foreman_snapshot_management/engine.rb +45 -11
  25. data/lib/foreman_snapshot_management/version.rb +1 -1
  26. data/test/controllers/api/v2/snapshots_test.rb +57 -0
  27. data/test/controllers/foreman_snapshot_management/snapshots_controller_test.rb +85 -0
  28. metadata +21 -6
  29. data/app/helpers/foreman_snapshot_management/snapshotadministration_helper.rb +0 -72
  30. data/test/unit/foreman_snapshot_management_test.rb +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 87811e930d27da1d7f48e95773f5ecbbf5b3749b
4
- data.tar.gz: 0c087f9e4acf4e7e9f2641bc3273f7ac664cc7f7
3
+ metadata.gz: '048b5bbc495a00c7caf44380c5ee03ccd319e592'
4
+ data.tar.gz: 7d331abbbb267a00c70485e8a74bb1e76d30f684
5
5
  SHA512:
6
- metadata.gz: 885cd0c2fbe5618f983515f92311be0d96b4c63eabee541545991716aa9ca0819cacf40ead72c94f1c4d5bed49a0ad69dc6613d9c4417fcc59e687f07e24ec64
7
- data.tar.gz: 130883c8f6a36407ef07d8724530d29ba06397d69b404b0927a6210fcd2c90d5d3e2d0e5070136da787a8a7950ecf71e6df2741daffbec2d3e86ea0cc6432ec8
6
+ metadata.gz: c2f5363bbd5646c3cd7383968fa0529ba483c9e42a0adcf1d483c6668cb5c5e43c8fdf19f46449658ceb07864022ce108644f0697724e4499fe1a493852e0018
7
+ data.tar.gz: 473771e206b8768650d3085c7494f5b7b4a07c3859894bb7573a2acfff2e4501c44915eb0c545bcadc4938a3efa862d1b1e070aff1ce6525bea147d34971ed74
data/README.md CHANGED
@@ -13,3 +13,12 @@ As Hypervisor VMware vSphere is supported.
13
13
  ## Installation
14
14
 
15
15
  See [How_to_Install_a_Plugin](http://projects.theforeman.org/projects/foreman/wiki/How_to_Install_a_Plugin) for how to install Foreman plugins
16
+
17
+ ## Copyright
18
+ Copyright (c) 2017 ATIX AG - http://www.atix.de
19
+
20
+ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
21
+
22
+ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
23
+
24
+ You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.
data/Rakefile CHANGED
File without changes
@@ -0,0 +1,107 @@
1
+ module Api
2
+ module V2
3
+ class SnapshotsController < V2::BaseController
4
+ include Api::Version2
5
+ include Foreman::Controller::Parameters::Snapshot
6
+
7
+ before_action :find_required_nested_object
8
+ before_action :check_snapshot_capability
9
+ before_action :find_resource, :only => %w[show update destroy revert]
10
+
11
+ api :GET, 'hosts/:host_id/snapshots/', N_('List all snapshots')
12
+ param :host_id, :identifier_dottable, :required => true
13
+ def index
14
+ @snapshots = resource_scope_for_index
15
+ end
16
+
17
+ api :GET, '/hosts/:host_id/snapshots/:id', 'Show a snapshot'
18
+ param :host_id, :identifier_dottable, :required => true
19
+ param :id, :identifier_dottable, :required => true
20
+
21
+ def show; end
22
+
23
+ def_param_group :snapshot do
24
+ param :snapshot, Hash, :required => true, :action_aware => true do
25
+ param :name, String, :required => true, :desc => N_('Name of this snapshot')
26
+ param :description, String, :desc => N_('Description of this snapshot')
27
+ end
28
+ end
29
+
30
+ api :POST, '/hosts/:host_id/snapshots/', N_('Create a snapshot')
31
+ param :host_id, :identifier_dottable, :required => true
32
+ param_group :snapshot, :as => :create
33
+
34
+ def create
35
+ @snapshot = resource_class.new(snapshot_params.to_h.merge(host: @nested_obj))
36
+ process_response @snapshot.save
37
+ end
38
+
39
+ api :PUT, '/hosts/:host_id/snapshots/:id/', N_('Update a snapshot')
40
+ param :host_id, :identifier_dottable, :required => true
41
+ param :id, :identifier_dottable, :required => true
42
+ param_group :snapshot
43
+
44
+ def update
45
+ process_response @snapshot.update_attributes(snapshot_params)
46
+ end
47
+
48
+ api :DELETE, '/hosts/:host_id/snapshots/:id', N_('Delete a snapshot')
49
+ param :host_id, :identifier_dottable, :required => true
50
+ param :id, :identifier_dottable, :required => true
51
+
52
+ def destroy
53
+ process_response @snapshot.destroy
54
+ end
55
+
56
+ api :PUT, '/hosts/:host_id/snapshots/:id/revert', N_('Revert Host to a snapshot')
57
+ param :host_id, :identifier_dottable, :required => true
58
+ param :id, :identifier_dottable, :required => true
59
+
60
+ def revert
61
+ process_response @snapshot.revert
62
+ end
63
+
64
+ private
65
+
66
+ def resource_scope(_options = {})
67
+ # TODO: Ask host for snapshots
68
+ @resource_scope ||= resource_class.all_for_host(@nested_obj)
69
+ end
70
+
71
+ def resource_scope_for_index
72
+ resource_scope.paginate(paginate_options)
73
+ end
74
+
75
+ def resource_class
76
+ ::ForemanSnapshotManagement::Snapshot
77
+ end
78
+
79
+ def find_resource
80
+ @snapshot = resource_class.find_for_host(@nested_obj, params[:id])
81
+ not_found unless @snapshot
82
+ end
83
+
84
+ def check_snapshot_capability
85
+ not_found unless @nested_obj.compute_resource && @nested_obj.compute_resource.capabilities.include?(:snapshots)
86
+ end
87
+
88
+ def action_permission
89
+ case params[:action]
90
+ when 'revert'
91
+ :revert
92
+ else
93
+ super
94
+ end
95
+ end
96
+
97
+ def parent_permission(child_permission)
98
+ case child_permission.to_s
99
+ when 'revert'
100
+ :edit
101
+ else
102
+ super
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,15 @@
1
+ module Foreman::Controller::Parameters::Snapshot
2
+ extend ActiveSupport::Concern
3
+
4
+ class_methods do
5
+ def snapshot_params_filter
6
+ Foreman::ParameterFilter.new(::ForemanSnapshotManagement::Snapshot).tap do |filter|
7
+ filter.permit :name, :description
8
+ end
9
+ end
10
+ end
11
+
12
+ def snapshot_params
13
+ self.class.snapshot_params_filter.filter_params(params, parameter_filter_context)
14
+ end
15
+ end
@@ -1,6 +1,9 @@
1
1
  module ForemanSnapshotManagement
2
2
  class SnapshotsController < ApplicationController
3
+ include ::Foreman::Controller::Parameters::Snapshot
4
+
3
5
  before_action :find_host
6
+ before_action :check_snapshot_capability
4
7
  before_action :enumerate_snapshots, only: [:index]
5
8
  before_action :find_snapshot, only: %i[destroy revert update]
6
9
  helper_method :xeditable?
@@ -18,26 +21,13 @@ module ForemanSnapshotManagement
18
21
  #
19
22
  # This method creates a Snapshot with a given name and optional description.
20
23
  def create
21
- # Create snapshot
22
- name = params['snapshot']['name']
23
- description = params['snapshot']['description'] || ''
24
- snapshot = Snapshot.new(host: @host, name: name, description: description)
25
- begin
26
- task = snapshot.create
27
-
28
- # Check state of Snapshot creation
29
- if task['task_state'] == 'success'
30
- status = _('Snapshot successfully created')
31
- else
32
- status = _('Error occurred while creating snapshot: %s') % task['task_state']
33
- end
34
-
35
- # Redirect to specific Host page
36
- redirect_to host_path(@host, anchor: 'snapshots'), flash: { notice: status }
37
- rescue
38
- logger.error 'Failed to take snapshot.'
39
- status = _('Error occurred while creating snapshot.')
40
- redirect_to host_path(@host, anchor: 'snapshots'), flash: { error: status }
24
+ @snapshot = Snapshot.new(snapshot_params.merge(host: @host))
25
+
26
+ if @snapshot.create
27
+ process_success
28
+ else
29
+ msg = _('Error occurred while creating Snapshot: %s') % @snapshot.errors.full_messages.to_sentence
30
+ process_error :error_msg => msg
41
31
  end
42
32
  end
43
33
 
@@ -45,51 +35,35 @@ module ForemanSnapshotManagement
45
35
  #
46
36
  # This method removes a Snapshot from a given host.
47
37
  def destroy
48
- # Remove Snapshot
49
- task = @snapshot.destroy
50
-
51
- # Check state of Snapshot creation
52
- if task['task_state'] == 'success'
53
- status = 'Snapshot successfully deleted'
38
+ if @snapshot.destroy
39
+ process_success
54
40
  else
55
- status = 'Error occurred while removing Snapshot: ' + task['task_state']
41
+ msg = _('Error occurred while removing Snapshot: %s') % @snapshot.errors.full_messages.to_sentence
42
+ process_error :error_msg => msg
56
43
  end
57
-
58
- # Redirect to specific Host page
59
- redirect_to host_path(@host, anchor: 'snapshots'), flash: { notice: status }
60
44
  end
61
45
 
62
46
  # Revert Snapshot
63
47
  #
64
48
  # This method reverts a host to a given Snapshot.
65
49
  def revert
66
- # Revert Snapshot
67
- task = @snapshot.revert
68
-
69
- # Check state of Snapshot creation
70
- if task['state'] == 'success'
71
- status = _('VM successfully rolled back')
50
+ if @snapshot.revert
51
+ process_success :success_msg => _('VM successfully rolled back.')
72
52
  else
73
- status = _('Error occurred while rolling back VM: %s') % task['state']
53
+ msg = _('Error occurred while rolling back VM: %s') % @snapshot.errors.full_messages.to_sentence
54
+ process_error :error_msg => msg
74
55
  end
75
-
76
- # Redirect to specific Host page
77
- redirect_to host_path(@host, anchor: 'snapshots'), flash: { notice: status }
78
56
  end
79
57
 
80
58
  # Update Snapshot
81
59
  #
82
60
  # This method renames a Snapshot from a given host.
83
61
  def update
84
- # Rename Snapshot
85
- @snapshot.name = params['snapshot']['name'] if params['snapshot']['name']
86
- @snapshot.description = params['snapshot']['description'] if params['snapshot']['description']
87
- begin
88
- task = @snapshot.save
62
+ if @snapshot.update_attributes(snapshot_params)
89
63
  render json: { name: @snapshot.name, description: @snapshot.description }
90
- rescue
91
- logger.error "Failed to update snapshot #{@snapshot.id}."
92
- render json: { errors: _('Failed to update snapshot.') }, status: :unprocessable_entity
64
+ else
65
+ msg = _('Failed to update Snapshot: %s') % @snapshot.errors.full_messages.to_sentence
66
+ render json: { errors: msg }, status: :unprocessable_entity
93
67
  end
94
68
  end
95
69
 
@@ -100,18 +74,62 @@ module ForemanSnapshotManagement
100
74
  private
101
75
 
102
76
  def find_host
103
- @host = Host.find_by! name: params['host_id']
104
- rescue => e
105
- process_ajax_error e, 'Host not found!'
77
+ host_id = params[:host_id]
78
+ if host_id.blank?
79
+ not_found
80
+ return false
81
+ end
82
+ @host = Host.authorized(host_permission).friendly.find(host_id)
83
+ unless @host
84
+ not_found
85
+ return(false)
86
+ end
87
+ end
88
+
89
+ def host_permission
90
+ case action_permission.to_s
91
+ when 'create', 'destroy'
92
+ 'edit'
93
+ when 'edit', 'view'
94
+ 'view'
95
+ when 'revert'
96
+ 'revert'
97
+ else
98
+ raise ::Foreman::Exception.new(N_('unknown host permission for %s'), "#{params[:controller]}##{action_permission}")
99
+ end
100
+ end
101
+
102
+ def action_permission
103
+ case params[:action]
104
+ when 'revert'
105
+ :revert
106
+ else
107
+ super
108
+ end
109
+ end
110
+
111
+ def check_snapshot_capability
112
+ not_found unless @host.compute_resource && @host.compute_resource.capabilities.include?(:snapshots)
106
113
  end
107
114
 
108
115
  def enumerate_snapshots
109
- # Hash of Snapshot
110
- @snapshots = Snapshot.all_for_host @host
116
+ # Array of Snapshot Objects
117
+ @snapshots = Snapshot.all_for_host(@host)
111
118
  end
112
119
 
113
120
  def find_snapshot
114
- @snapshot = Snapshot.find_for_host @host, params['id']
121
+ @snapshot = Snapshot.find_for_host(@host, params['id'])
122
+ not_found unless @snapshot
123
+ end
124
+
125
+ def process_success(hash = {})
126
+ hash[:success_redirect] ||= host_path(@host, anchor: 'snapshots')
127
+ super(hash)
128
+ end
129
+
130
+ def process_error(hash = {})
131
+ hash[:redirect] ||= host_path(@host, anchor: 'snapshots')
132
+ super(hash)
115
133
  end
116
134
  end
117
135
  end
@@ -0,0 +1,33 @@
1
+ module FogExtensions
2
+ module Vsphere
3
+ module Snapshots
4
+ module Mock
5
+ # Overwrite this to stop infinite recursion
6
+ # TODO: Add proper test data
7
+ def list_child_snapshots(_snapshot, _opts = {})
8
+ [
9
+ ]
10
+ end
11
+
12
+ def remove_snapshot(options = {})
13
+ raise ArgumentError, 'snapshot is a required parameter' unless options.key? 'snapshot'
14
+ raise ArgumentError, 'removeChildren is a required parameter' unless options.key? 'removeChildren'
15
+
16
+ {
17
+ 'task_state' => 'success'
18
+ }
19
+ end
20
+
21
+ def rename_snapshot(options = {})
22
+ raise ArgumentError, 'snapshot is a required parameter' unless options.key? 'snapshot'
23
+ raise ArgumentError, 'name is a required parameter' unless options.key? 'name'
24
+ raise ArgumentError, 'description is a required parameter' unless options.key? 'description'
25
+
26
+ {
27
+ 'task_state' => 'success'
28
+ }
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,43 @@
1
+ module FogExtensions
2
+ module Vsphere
3
+ module Snapshots
4
+ module Real
5
+ # Extends fog-vsphere gem for a remove Snapshot method.
6
+ def remove_snapshot(options = {})
7
+ raise ArgumentError, 'snapshot is a required parameter' unless options.key? 'snapshot'
8
+ raise ArgumentError, 'removeChildren is a required parameter' unless options.key? 'removeChildren'
9
+
10
+ unless ::Fog::Compute::Vsphere::Snapshot === options['snapshot']
11
+ raise ArgumentError, 'snapshot is a required parameter'
12
+ end
13
+
14
+ task = options['snapshot'].mo_ref.RemoveSnapshot_Task(
15
+ removeChildren: options['removeChildren']
16
+ )
17
+ task.wait_for_completion
18
+
19
+ {
20
+ 'task_state' => task.info.state
21
+ }
22
+ end
23
+
24
+ # Extends fog-vsphere gem for a rename Snapshot method.
25
+ # Does not have a return value, VMWare API throws a fault if there are errors
26
+ def rename_snapshot(options = {})
27
+ raise ArgumentError, 'snapshot is a required parameter' unless options.key? 'snapshot'
28
+ raise ArgumentError, 'name is a required parameter' unless options.key? 'name'
29
+ raise ArgumentError, 'description is a required parameter' unless options.key? 'description'
30
+
31
+ unless ::Fog::Compute::Vsphere::Snapshot === options['snapshot']
32
+ raise ArgumentError, 'snapshot is a required parameter'
33
+ end
34
+
35
+ options['snapshot'].mo_ref.RenameSnapshot(
36
+ name: options['name'],
37
+ description: options['description']
38
+ )
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -1,73 +1,131 @@
1
+ require 'date'
2
+
1
3
  module ForemanSnapshotManagement
2
4
  class Snapshot
3
5
  extend ActiveModel::Callbacks
4
6
  include ActiveModel::Conversion
5
7
  include ActiveModel::Model
6
8
  include ActiveModel::Dirty
9
+ include ActiveModel::ForbiddenAttributesProtection
7
10
 
8
11
  define_model_callbacks :create, :save, :destroy, :revert
9
- attr_accessor :id, :vmware_snapshot, :name, :description, :host_id
12
+ attr_accessor :id, :raw_snapshot, :name, :description, :host_id, :parent, :create_time
10
13
 
11
- def self.add_snapshot_with_children(snapshots, host, vmware_snapshot)
12
- snapshots[vmware_snapshot.ref] = new_from_vmware(host, vmware_snapshot)
13
- vmware_snapshot.child_snapshots.each do |snap|
14
- add_snapshot_with_children(snapshots, host, snap)
14
+ def self.all_for_host(host)
15
+ snapshots = host.compute_resource.get_snapshots(host.uuid).map do |raw_snapshot|
16
+ new_from_vmware(host, raw_snapshot)
15
17
  end
16
18
  end
17
19
 
18
- def self.all_for_host(host)
19
- snapshots = {}
20
- root_snapshot = host.compute_resource.get_snapshots(host.uuid).first
21
- add_snapshot_with_children(snapshots, host, root_snapshot) if root_snapshot
22
- snapshots
20
+ def self.find_for_host(host, id)
21
+ raw_snapshot = host.compute_resource.get_snapshot(host.uuid, id)
22
+ new_from_vmware(host, raw_snapshot)
23
23
  end
24
24
 
25
- def self.find_for_host(host, id)
26
- all_for_host(host)[id]
25
+ def self.new_from_vmware(host, raw_snapshot, opts = {})
26
+ new(
27
+ host: host,
28
+ id: raw_snapshot.ref,
29
+ raw_snapshot: raw_snapshot,
30
+ name: raw_snapshot.name,
31
+ description: raw_snapshot.description,
32
+ parent: opts[:parent],
33
+ create_time: raw_snapshot.create_time
34
+ )
35
+ end
36
+
37
+ def children
38
+ return [] unless raw_snapshot
39
+ child_snapshots = raw_snapshot.child_snapshots.flat_map do |child_snapshot|
40
+ self.class.new_from_vmware(host, child_snapshot, parent: self)
41
+ end
42
+ child_snapshots + child_snapshots.flat_map(&:children)
43
+ end
44
+
45
+ def inspect
46
+ "#<#{self.class}:0x#{self.__id__.to_s(16)} name=#{name} id=#{id} description=#{description} host_id=#{host_id} parent=#{parent.try(:id)} children=#{children.map(&:id).inspect}>"
47
+ end
48
+
49
+ def to_s
50
+ _('Snapshot')
27
51
  end
28
52
 
29
- def self.new_from_vmware(host, vmware_snapshot)
30
- new(host: host, id: vmware_snapshot.ref, vmware_snapshot: vmware_snapshot, name: vmware_snapshot.name, description: vmware_snapshot.description)
53
+ def formatted_create_time()
54
+ create_time.strftime("%F %H:%M")
31
55
  end
32
56
 
33
57
  def persisted?
34
- @id.present?
58
+ self.id.present?
35
59
  end
36
60
 
37
61
  # host accessors
38
62
  def host
39
- Host.find(@host_id)
63
+ Host.find(self.host_id)
40
64
  end
41
65
 
42
66
  def host=(host)
43
- @host_id = host.id
67
+ self.host_id = host.id
68
+ end
69
+
70
+ def create_time
71
+ raw_snapshot.try(:create_time)
72
+ end
73
+
74
+ def assign_attributes(new_attributes)
75
+ attributes = new_attributes.stringify_keys
76
+ attributes = sanitize_for_mass_assignment(attributes)
77
+ attributes.each do |k, v|
78
+ public_send("#{k}=", v)
79
+ end
80
+ end
81
+
82
+ def update_attributes(new_attributes)
83
+ assign_attributes(new_attributes)
84
+ save
44
85
  end
45
86
 
46
87
  # crud
47
88
  def create
48
89
  run_callbacks(:create) do
49
- host.compute_resource.create_snapshot(host.uuid, name, description)
90
+ handle_snapshot_errors do
91
+ host.compute_resource.create_snapshot(host.uuid, name, description)
92
+ end
50
93
  end
51
94
  end
52
95
 
53
96
  def save
54
97
  run_callbacks(:save) do
55
- host.compute_resource.update_snapshot(vmware_snapshot, name, description)
98
+ handle_snapshot_errors do
99
+ host.compute_resource.update_snapshot(raw_snapshot, name, description)
100
+ end
56
101
  end
57
102
  end
58
103
 
59
104
  def destroy
60
105
  run_callbacks(:destroy) do
61
- result = host.compute_resource.remove_snapshot(vmware_snapshot, false)
62
- id = nil
106
+ result = handle_snapshot_errors do
107
+ result = host.compute_resource.remove_snapshot(raw_snapshot, false)
108
+ end
109
+ self.id = nil
63
110
  result
64
111
  end
65
112
  end
66
113
 
67
114
  def revert
68
115
  run_callbacks(:revert) do
69
- host.compute_resource.revert_snapshot(vmware_snapshot)
116
+ handle_snapshot_errors do
117
+ host.compute_resource.revert_snapshot(raw_snapshot)
118
+ end
70
119
  end
71
120
  end
121
+
122
+ private
123
+
124
+ def handle_snapshot_errors
125
+ yield
126
+ rescue Foreman::WrappedException => e
127
+ errors.add(:base, e.wrapped_exception.message)
128
+ false
129
+ end
72
130
  end
73
131
  end
@@ -1,26 +1,41 @@
1
1
  module ForemanSnapshotManagement
2
2
  module VmwareExtensions
3
- extend ActiveSupport::Concern
3
+ # Extend VMWare's capabilities with snapshots.
4
+ def capabilities
5
+ super + [:snapshots]
6
+ end
4
7
 
5
8
  # Create a Snapshot.
6
9
  #
7
10
  # This method creates a Snapshot with a given name and optional description.
8
11
  def create_snapshot(uuid, name, description)
9
- client.vm_take_snapshot('instance_uuid' => uuid, 'name' => name, 'description' => description)
12
+ task = client.vm_take_snapshot('instance_uuid' => uuid, 'name' => name, 'description' => description)
13
+ task_successful?(task)
14
+ rescue RbVmomi::Fault => e
15
+ Foreman::Logging.exception('Error creating VMWare Snapshot', e)
16
+ raise ::Foreman::WrappedException.new(e, N_('Unable to create VMWare Snapshot'))
10
17
  end
11
18
 
12
19
  # Remove Snapshot
13
20
  #
14
21
  # This method removes a Snapshot from a given host.
15
- def remove_snapshot(snapshot, removeChildren)
16
- client.remove_snapshot('snapshot' => snapshot, 'removeChildren' => removeChildren)
22
+ def remove_snapshot(snapshot, remove_children)
23
+ task = client.remove_snapshot('snapshot' => snapshot, 'removeChildren' => remove_children)
24
+ task_successful?(task)
25
+ rescue RbVmomi::Fault => e
26
+ Foreman::Logging.exception('Error removing VMWare Snapshot', e)
27
+ raise ::Foreman::WrappedException.new(e, N_('Unable to remove VMWare Snapshot'))
17
28
  end
18
29
 
19
30
  # Revert Snapshot
20
31
  #
21
32
  # This method revert a host to a given Snapshot.
22
33
  def revert_snapshot(snapshot)
23
- client.revert_to_snapshot(snapshot)
34
+ task = client.revert_to_snapshot(snapshot)
35
+ task_successful?(task)
36
+ rescue RbVmomi::Fault => e
37
+ Foreman::Logging.exception('Error reverting VMWare Snapshot', e)
38
+ raise ::Foreman::WrappedException.new(e, N_('Unable to revert VMWare Snapshot'))
24
39
  end
25
40
 
26
41
  # Update Snapshot
@@ -28,13 +43,30 @@ module ForemanSnapshotManagement
28
43
  # This method renames a Snapshot from a given host.
29
44
  def update_snapshot(snapshot, name, description)
30
45
  client.rename_snapshot('snapshot' => snapshot, 'name' => name, 'description' => description)
46
+ true
47
+ rescue RbVmomi::Fault => e
48
+ Foreman::Logging.exception('Error updating VMWare Snapshot', e)
49
+ raise ::Foreman::WrappedException.new(e, N_('Unable to update VMWare Snapshot'))
50
+ end
51
+
52
+ # Get Snapshot
53
+ #
54
+ # This methods returns a specific Snapshot for a given host.
55
+ def get_snapshot(server_id, snapshot_id)
56
+ client.snapshots(server_id: server_id).get(snapshot_id)
31
57
  end
32
58
 
33
59
  # Get Snapshots
34
60
  #
35
61
  # This methods returns Snapshots from a given host.
36
62
  def get_snapshots(server_id)
37
- client.snapshots(server_id: server_id)
63
+ client.snapshots(server_id: server_id).all(recursive: true)
64
+ end
65
+
66
+ private
67
+
68
+ def task_successful?(task)
69
+ task['task_state'] == 'success' || task['state'] == 'success'
38
70
  end
39
71
  end
40
72
  end
@@ -1,21 +1,11 @@
1
- tab = "<% if @host.provider == 'VMware' %>
2
- <li><a href='#snapshots' data-toggle='tab'><%= _('Snapshots') %></a></li>
3
- <% end %>"
4
-
5
- tab_content = "<div id='snapshots' class='tab-pane'
6
- data-ajax-url='<%= host_snapshots_path(host_id: @host)%>'
7
- data-on-complete='onContentLoad'>
8
- <%= spinner(_('Loading Parameters information ...')) %>
9
- </div>"
10
-
11
1
  # Add a Snapshots tab in the view of a host
12
2
  Deface::Override.new(virtual_path: 'hosts/show',
13
3
  name: 'add_host_snapshot_tab',
14
4
  insert_bottom: 'ul',
15
- text: tab)
5
+ partial: 'foreman_snapshot_management/hosts/snapshots_tab')
16
6
 
17
7
  # Load content of Snapshots tab
18
8
  Deface::Override.new(virtual_path: 'hosts/show',
19
9
  name: 'add_host_snapshots_tab_content',
20
10
  insert_bottom: 'div#myTabContent',
21
- text: tab_content)
11
+ partial: 'foreman_snapshot_management/hosts/snapshots_tab_content')
@@ -0,0 +1,3 @@
1
+ object @snapshot
2
+
3
+ attributes :id, :name
@@ -0,0 +1,3 @@
1
+ object @snapshot
2
+
3
+ extends 'api/v2/snapshots/show'
@@ -0,0 +1,3 @@
1
+ object @snapshot
2
+
3
+ extends 'api/v2/snapshots/show'
@@ -0,0 +1,3 @@
1
+ collection @snapshots
2
+
3
+ extends 'api/v2/snapshots/main'
@@ -0,0 +1,9 @@
1
+ object @snapshot
2
+
3
+ extends 'api/v2/snapshots/base'
4
+
5
+ attributes :description
6
+
7
+ node(:created_at, &:create_time)
8
+ node(:parent_id) { |snapshot| snapshot.parent.try(:id) }
9
+ node(:children_ids) { |snapshot| snapshot.children.map(&:id) }
@@ -0,0 +1,3 @@
1
+ object @snapshot
2
+
3
+ extends 'api/v2/snapshots/show'
@@ -0,0 +1,3 @@
1
+ object @snapshot
2
+
3
+ extends 'api/v2/snapshots/main'
@@ -0,0 +1,3 @@
1
+ object @snapshot
2
+
3
+ extends 'api/v2/snapshots/show'
@@ -0,0 +1,3 @@
1
+ <% if @host.compute_resource && @host.compute_resource.capabilities.include?(:snapshots) && authorized_for(:controller => 'foreman_snapshot_management/snapshots', :action => :index) %>
2
+ <li><a href='#snapshots' data-toggle='tab'><%= _('Snapshots') %></a></li>
3
+ <% end %>
@@ -0,0 +1,7 @@
1
+ <% if @host.compute_resource && @host.compute_resource.capabilities.include?(:snapshots) && authorized_for(:controller => 'foreman_snapshot_management/snapshots', :action => :index) %>
2
+ <div id='snapshots' class='tab-pane'
3
+ data-ajax-url='<%= host_snapshots_path(host_id: @host)%>'
4
+ data-on-complete='onContentLoad'>
5
+ <%= spinner(_('Loading Snapshots information ...')) %>
6
+ </div>
7
+ <% end %>
@@ -8,29 +8,40 @@
8
8
  </tr>
9
9
  </thead>
10
10
  <tbody>
11
- <tr>
12
- <td>
13
- <%= f.text_field :name, class: 'form-control' %>
14
- </td>
15
- <td>
16
- <%= f.text_field :description, class: 'form-control' %>
17
- </td>
18
- <td>
19
- <%= f.submit _('Create'), class: 'btn btn-success' %>
20
- </td>
21
- </tr>
22
- <% @snapshots.each do |ref, snap| %>
11
+ <% if authorized_for(:controller => 'foreman_snapshot_management/snapshots', :action => :create) %>
23
12
  <tr>
24
13
  <td>
25
- <%= edit_textfield snap, :name %>
14
+ <%= f.text_field :name, class: 'form-control' %>
26
15
  </td>
27
16
  <td>
28
- <%= edit_textarea snap, :description %>
17
+ <%= f.text_field :description, class: 'form-control' %>
18
+ </td>
19
+ <td>
20
+ <%= f.submit _('Create'), class: 'btn btn-success' %>
21
+ </td>
22
+ </tr>
23
+ <% end %>
24
+ <% @snapshots.each do |snapshot| %>
25
+ <tr>
26
+ <td>
27
+ <% if authorized_for(:controller => 'foreman_snapshot_management/snapshots', :action => :edit) %>
28
+ <%= edit_textfield snapshot, :name %>
29
+ <% else %>
30
+ <%= snapshot.name %>
31
+ <% end %>
32
+ <br /><%= snapshot.formatted_create_time() %>
33
+ </td>
34
+ <td>
35
+ <% if authorized_for(:controller => 'foreman_snapshot_management/snapshots', :action => :edit) %>
36
+ <%= edit_textarea snapshot, :description %>
37
+ <% else %>
38
+ <%= snapshot.description %>
39
+ <% end %>
29
40
  </td>
30
41
  <td>
31
42
  <%= action_buttons(
32
- display_link_if_authorized(_('Rollback'), hash_for_revert_host_snapshot_path(host_id: @host, id: ref), method: :put, class: 'btn btn-primary', data: {confirm: _("Are you sure to revert this Snapshot?")}),
33
- display_delete_if_authorized(hash_for_host_snapshot_path(host_id: @host, id: ref), data: {confirm: _("Are you sure to delete this Snapshot?")}),
43
+ display_link_if_authorized(_('Rollback'), hash_for_revert_host_snapshot_path(host_id: @host, id: snapshot.id), method: :put, class: 'btn btn-primary', data: {confirm: _("Are you sure to revert this Snapshot?")}),
44
+ display_delete_if_authorized(hash_for_host_snapshot_path(host_id: @host, id: snapshot.id), data: {confirm: _("Are you sure to delete this Snapshot?")}),
34
45
  ) %>
35
46
  </td>
36
47
  </tr>
@@ -1,4 +1,21 @@
1
1
  Rails.application.routes.draw do
2
+ namespace :api, :defaults => { :format => 'json' } do
3
+ scope '(:apiv)', :module => :v2,
4
+ :defaults => { :apiv => 'v2' },
5
+ :apiv => /v1|v2/,
6
+ :constraints => ApiConstraints.new(:version => 2, :default => true) do
7
+ constraints(:host_id => /[^\/]+/) do
8
+ resources :hosts, :only => [] do
9
+ constraints(:id => /[^\/]+/) do
10
+ resources :snapshots, except: [:new, :edit] do
11
+ put :revert, :on => :collection
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+
2
19
  constraints(host_id: %r{[^\/]+}) do
3
20
  resources :hosts, only: [] do
4
21
  resources :snapshots, module: 'foreman_snapshot_management' do
@@ -4,25 +4,52 @@ module ForemanSnapshotManagement
4
4
  class Engine < ::Rails::Engine
5
5
  engine_name 'foreman_snapshot_management'
6
6
 
7
- config.autoload_paths += Dir["#{config.root}/app/controllers/foreman_snapshot_management/"]
8
- config.autoload_paths += Dir["#{config.root}/app/helpers/foreman_snapshot_management/"]
9
- config.autoload_paths += Dir["#{config.root}/app/models/foreman_snapshot_management"]
10
- config.autoload_paths += Dir["#{config.root}/app/overrides"]
7
+ config.autoload_paths += Dir["#{config.root}/app/models/concerns"]
8
+ config.autoload_paths += Dir["#{config.root}/app/controllers/concerns"]
11
9
 
12
10
  initializer 'foreman_snapshot_management.register_plugin', before: :finisher_hook do |_app|
13
11
  Foreman::Plugin.register :foreman_snapshot_management do
14
12
  requires_foreman '>= 1.14'
15
13
 
14
+ apipie_documented_controllers ["#{ForemanSnapshotManagement::Engine.root}/app/controllers/api/v2/*.rb"]
15
+
16
16
  # Add permissions
17
17
  security_block :foreman_snapshot_management do
18
- permission :view_foreman_snapshot_management, :'foreman_snapshot_management/hosts' => [:new_action]
19
- permission :view_foreman_snapshot_management, :'foreman_snapshot_management/virtualmachines' => [:index]
20
- permission :view_foreman_snapshot_management, :'foreman_snapshot_management/createsnapshot' => [:index]
21
- permission :view_foreman_snapshot_management, :'foreman_snapshot_management/createsnapshot' => [:createSnapshot]
18
+ permission :view_snapshots, {
19
+ :'foreman_snapshot_management/snapshots' => [:index],
20
+ :'api/v2/snapshots' => [:index, :show]
21
+ }, :resource_type => 'Host'
22
+
23
+ permission :create_snapshots, {
24
+ :'foreman_snapshot_management/snapshots' => [:create],
25
+ :'api/v2/snapshots' => [:create]
26
+ }, :resource_type => 'Host'
27
+
28
+ permission :edit_snapshots, {
29
+ :'foreman_snapshot_management/snapshots' => [:update],
30
+ :'api/v2/snapshots' => [:update]
31
+ }, :resource_type => 'Host'
32
+
33
+ permission :destroy_snapshots, {
34
+ :'foreman_snapshot_management/snapshots' => [:destroy],
35
+ :'api/v2/snapshots' => [:destroy]
36
+ }, :resource_type => 'Host'
37
+
38
+ permission :revert_snapshots, {
39
+ :'foreman_snapshot_management/snapshots' => [:revert],
40
+ :'api/v2/snapshots' => [:revert]
41
+ }, :resource_type => 'Host'
22
42
  end
23
43
 
24
- # Add a new role called 'ForemanSnapshotManagement' if it doesn't exist
25
- role 'ForemanSnapshotManagement', [:view_foreman_snapshot_management]
44
+ # Adds roles if they do not exist
45
+ role 'Snapshot Viewer', [:view_snapshots]
46
+ role 'Snapshot Manager', [
47
+ :view_snapshots,
48
+ :create_snapshots,
49
+ :edit_snapshots,
50
+ :destroy_snapshots,
51
+ :revert_snapshots
52
+ ]
26
53
  end
27
54
  end
28
55
 
@@ -45,7 +72,14 @@ module ForemanSnapshotManagement
45
72
  # Include concerns in this config.to_prepare block
46
73
  config.to_prepare do
47
74
  begin
48
- ::Foreman::Model::Vmware.send(:include, ForemanSnapshotManagement::VmwareExtensions)
75
+ # Load Foreman extensions
76
+ ::Foreman::Model::Vmware.send(:prepend, ForemanSnapshotManagement::VmwareExtensions)
77
+
78
+ # Load Fog extensions
79
+ if Foreman::Model::Vmware.available?
80
+ Fog::Compute::Vsphere::Real.send(:prepend, FogExtensions::Vsphere::Snapshots::Real)
81
+ Fog::Compute::Vsphere::Mock.send(:prepend, FogExtensions::Vsphere::Snapshots::Mock)
82
+ end
49
83
  rescue => e
50
84
  Rails.logger.warn "ForemanSnapshotManagement: skipping engine hook (#{e})"
51
85
  end
@@ -1,3 +1,3 @@
1
1
  module ForemanSnapshotManagement
2
- VERSION = '1.0.0'.freeze
2
+ VERSION = '1.1.0'.freeze
3
3
  end
@@ -0,0 +1,57 @@
1
+ require 'test_helper'
2
+
3
+ class Api::V2::SnapshotsControllerTest < ActionController::TestCase
4
+ let(:compute_resource) do
5
+ cr = FactoryGirl.create(:compute_resource, :vmware, :uuid => 'Solutions')
6
+ ComputeResource.find_by_id(cr.id)
7
+ end
8
+ let(:uuid) { '5032c8a5-9c5e-ba7a-3804-832a03e16381' }
9
+ let(:host) { FactoryGirl.create(:host, :managed, :compute_resource => compute_resource, :uuid => uuid) }
10
+ let(:snapshot_id) { 'snapshot-0101' }
11
+ setup { ::Fog.mock! }
12
+ teardown { ::Fog.unmock! }
13
+
14
+ test 'should get index' do
15
+ get :index, { :host_id => host.to_param }
16
+ assert_response :success
17
+ assert_not_nil assigns(:snapshots)
18
+ body = ActiveSupport::JSON.decode(@response.body)
19
+ refute_empty body
20
+ refute_empty body['results']
21
+ end
22
+
23
+ test 'should show snapshot' do
24
+ get :show, { :host_id => host.to_param, :id => snapshot_id }
25
+ assert_not_nil assigns(:snapshot)
26
+ assert_response :success
27
+ body = ActiveSupport::JSON.decode(@response.body)
28
+ refute_empty body
29
+ end
30
+
31
+ test 'should 404 for unknown snapshot' do
32
+ get :show, { :host_id => host.to_param, :id => 'does-not-exist' }
33
+ assert_response :not_found
34
+ end
35
+
36
+ test 'should create snapshot' do
37
+ post :create, { :host_id => host.to_param, :name => 'test' }
38
+ assert_response :created
39
+ assert_not_nil assigns(:snapshot)
40
+ end
41
+
42
+ test 'should update snapshot' do
43
+ name = 'test'
44
+ put :update, { :host_id => host.to_param, :id => snapshot_id.to_param, :name => name.to_param }
45
+ assert_response :success
46
+ end
47
+
48
+ test 'should destroy snapshot' do
49
+ delete :destroy, { :host_id => host.to_param, :id => snapshot_id.to_param }
50
+ assert_response :success
51
+ end
52
+
53
+ test 'should revert snapshot' do
54
+ put :revert, { :host_id => host.to_param, :id => snapshot_id.to_param }
55
+ assert_response :success
56
+ end
57
+ end
@@ -0,0 +1,85 @@
1
+ require 'test_helper'
2
+
3
+ module ForemanSnapshotManagement
4
+ class SnapshotsControllerTest < ActionController::TestCase
5
+ let(:compute_resource) do
6
+ cr = FactoryGirl.create(:compute_resource, :vmware, :uuid => 'Solutions')
7
+ ComputeResource.find_by_id(cr.id)
8
+ end
9
+ let(:uuid) { '5032c8a5-9c5e-ba7a-3804-832a03e16381' }
10
+ let(:host) { FactoryGirl.create(:host, :managed, :compute_resource => compute_resource, :uuid => uuid) }
11
+ let(:snapshot_id) { 'snapshot-0101' }
12
+ setup { ::Fog.mock! }
13
+ teardown { ::Fog.unmock! }
14
+
15
+ context 'GET #index' do
16
+ test 'should get index' do
17
+ get :index, { :host_id => host.to_param }, set_session_user
18
+ assert_response :success
19
+ assert_not_nil assigns(:snapshots)
20
+ assert_template 'foreman_snapshot_management/snapshots/_index'
21
+ end
22
+ end
23
+
24
+ context 'POST #create' do
25
+ test 'create valid' do
26
+ post :create, { :host_id => host.to_param, :snapshot => { :name => 'test' } }, set_session_user
27
+ assert_redirected_to host_url(host, :anchor => 'snapshots')
28
+ assert_includes flash[:notice], 'Successfully created Snapshot.'
29
+ end
30
+
31
+ test 'create invalid' do
32
+ ForemanSnapshotManagement::Snapshot.any_instance.stubs(:create).returns(false)
33
+ post :create, { :host_id => host.to_param, :snapshot => { :name => nil } }, set_session_user
34
+ assert_redirected_to host_url(host, :anchor => 'snapshots')
35
+ assert_includes flash[:error], 'Error occurred while creating Snapshot'
36
+ end
37
+ end
38
+
39
+ context 'DELETE #destroy' do
40
+ test 'destroy successful' do
41
+ delete :destroy, { :host_id => host.to_param, :id => snapshot_id }, set_session_user
42
+ assert_redirected_to host_url(host, :anchor => 'snapshots')
43
+ assert_includes flash[:notice], 'Successfully deleted Snapshot.'
44
+ end
45
+
46
+ test 'destroy with error' do
47
+ ForemanSnapshotManagement::Snapshot.any_instance.stubs(:destroy).returns(false)
48
+ delete :destroy, { :host_id => host.to_param, :id => snapshot_id }, set_session_user
49
+ assert_redirected_to host_url(host, :anchor => 'snapshots')
50
+ assert_includes flash[:error], 'Error occurred while removing Snapshot'
51
+ end
52
+ end
53
+
54
+ context 'PUT #revert' do
55
+ test 'revert successful' do
56
+ put :revert, { :host_id => host.to_param, :id => snapshot_id }, set_session_user
57
+ assert_redirected_to host_url(host, :anchor => 'snapshots')
58
+ assert_includes flash[:notice], 'VM successfully rolled back.'
59
+ end
60
+
61
+ test 'revert with error' do
62
+ ForemanSnapshotManagement::Snapshot.any_instance.stubs(:revert).returns(false)
63
+ put :revert, { :host_id => host.to_param, :id => snapshot_id }, set_session_user
64
+ assert_redirected_to host_url(host, :anchor => 'snapshots')
65
+ assert_includes flash[:error], 'Error occurred while rolling back VM'
66
+ end
67
+ end
68
+
69
+ context 'PUT #update' do
70
+ test 'update successful' do
71
+ data = { 'name' => 'test 2', 'description' => '' }
72
+ put :update, { :host_id => host.to_param, :id => snapshot_id, :snapshot => data }, set_session_user
73
+ assert_response :success
74
+ body = ActiveSupport::JSON.decode(@response.body)
75
+ assert_equal(data, body)
76
+ end
77
+
78
+ test 'update with error' do
79
+ ForemanSnapshotManagement::Snapshot.any_instance.stubs(:save).returns(false)
80
+ put :update, { :host_id => host.to_param, :id => snapshot_id, :snapshot => { :name => 'test 2' } }, set_session_user
81
+ assert_response :unprocessable_entity
82
+ end
83
+ end
84
+ end
85
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_snapshot_management
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ATIX AG
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-11 00:00:00.000000000 Z
11
+ date: 2017-09-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubocop
@@ -48,12 +48,25 @@ files:
48
48
  - LICENSE
49
49
  - README.md
50
50
  - Rakefile
51
+ - app/controllers/api/v2/snapshots_controller.rb
52
+ - app/controllers/concerns/foreman/controller/parameters/snapshot.rb
51
53
  - app/controllers/foreman_snapshot_management/snapshots_controller.rb
52
54
  - app/helpers/foreman_snapshot_management/snapshot_helper.rb
53
- - app/helpers/foreman_snapshot_management/snapshotadministration_helper.rb
55
+ - app/models/concerns/fog_extensions/vsphere/snapshots/mock.rb
56
+ - app/models/concerns/fog_extensions/vsphere/snapshots/real.rb
54
57
  - app/models/foreman_snapshot_management/snapshot.rb
55
58
  - app/models/foreman_snapshot_management/vmware_extensions.rb
56
59
  - app/overrides/hosts/add_tab_to_host_overview.rb
60
+ - app/views/api/v2/snapshots/base.json.rabl
61
+ - app/views/api/v2/snapshots/create.json.rabl
62
+ - app/views/api/v2/snapshots/destroy.json.rabl
63
+ - app/views/api/v2/snapshots/index.json.rabl
64
+ - app/views/api/v2/snapshots/main.json.rabl
65
+ - app/views/api/v2/snapshots/revert.json.rabl
66
+ - app/views/api/v2/snapshots/show.json.rabl
67
+ - app/views/api/v2/snapshots/update.json.rabl
68
+ - app/views/foreman_snapshot_management/hosts/_snapshots_tab.html.erb
69
+ - app/views/foreman_snapshot_management/hosts/_snapshots_tab_content.html.erb
57
70
  - app/views/foreman_snapshot_management/snapshots/_index.html.erb
58
71
  - config/routes.rb
59
72
  - lib/foreman_snapshot_management.rb
@@ -64,8 +77,9 @@ files:
64
77
  - locale/en/foreman_snapshot_management.po
65
78
  - locale/foreman_snapshot_management.pot
66
79
  - locale/gemspec.rb
80
+ - test/controllers/api/v2/snapshots_test.rb
81
+ - test/controllers/foreman_snapshot_management/snapshots_controller_test.rb
67
82
  - test/test_plugin_helper.rb
68
- - test/unit/foreman_snapshot_management_test.rb
69
83
  homepage: http://www.orcharhino.com
70
84
  licenses: []
71
85
  metadata: {}
@@ -85,10 +99,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
85
99
  version: '0'
86
100
  requirements: []
87
101
  rubyforge_project:
88
- rubygems_version: 2.5.2
102
+ rubygems_version: 2.5.2.1
89
103
  signing_key:
90
104
  specification_version: 4
91
105
  summary: Snapshot Management for VMware vSphere
92
106
  test_files:
107
+ - test/controllers/api/v2/snapshots_test.rb
108
+ - test/controllers/foreman_snapshot_management/snapshots_controller_test.rb
93
109
  - test/test_plugin_helper.rb
94
- - test/unit/foreman_snapshot_management_test.rb
@@ -1,72 +0,0 @@
1
- module ForemanSnapshotManagement
2
- module SnapshotadministrationHelper
3
- end
4
- end
5
-
6
- module Fog
7
- module Compute
8
- class Vsphere
9
- class Real
10
- # Extends fog-vsphere gem for a remove Snapshot method.
11
- def remove_snapshot(options = {})
12
- raise ArgumentError, 'snapshot is a required parameter' unless options.key? 'snapshot'
13
- raise ArgumentError, 'removeChildren is a required parameter' unless options.key? 'removeChildren'
14
-
15
- unless Snapshot === options['snapshot']
16
- raise ArgumentError, 'snapshot is a required parameter'
17
- end
18
-
19
- task = options['snapshot'].mo_ref.RemoveSnapshot_Task(
20
- removeChildren: options['removeChildren']
21
- )
22
- task.wait_for_completion
23
-
24
- {
25
- 'task_state' => task.info.state
26
- }
27
- end
28
-
29
- # Extends fog-vsphere gem for a rename Snapshot method.
30
- # TODO: Add info state
31
- def rename_snapshot(options = {})
32
- raise ArgumentError, 'snapshot is a required parameter' unless options.key? 'snapshot'
33
- raise ArgumentError, 'name is a required parameter' unless options.key? 'name'
34
- raise ArgumentError, 'description is a required parameter' unless options.key? 'description'
35
-
36
- unless Snapshot === options['snapshot']
37
- raise ArgumentError, 'snapshot is a required parameter'
38
- end
39
-
40
- task = options['snapshot'].mo_ref.RenameSnapshot(
41
- name: options['name'],
42
- description: options['description']
43
- )
44
- # task.wait_for_completion
45
-
46
- # {
47
- # 'task_state' => task.info.state
48
- # }
49
- end
50
- end
51
- class Mock
52
- def remove_snapshot(snapshot)
53
- raise ArgumentError, 'snapshot is a required parameter' unless options.key? 'snapshot'
54
- raise ArgumentError, 'removeChildren is a required parameter' unless options.key? 'removeChildren'
55
- raise ArgumentError, 'snapshot is a required parameter' if snapshot.nil?
56
- {
57
- 'task_state' => 'success'
58
- }
59
- end
60
-
61
- def rename_snapshot(_snapshot)
62
- raise ArgumentError, 'snapshot is a required parameter' unless options.key? 'snapshot'
63
- raise ArgumentError, 'name is a required parameter' unless options.key? 'name'
64
- raise ArgumentError, 'description is a required parameter' unless options.key? 'description'
65
- {
66
- 'task_state' => 'success'
67
- }
68
- end
69
- end
70
- end
71
- end
72
- end
@@ -1,11 +0,0 @@
1
- require 'test_plugin_helper'
2
-
3
- class ForemanSnapshotManagementTest < ActiveSupport::TestCase
4
- setup do
5
- User.current = User.find_by_login 'admin'
6
- end
7
-
8
- test 'the truth' do
9
- assert true
10
- end
11
- end