foreman_snapshot_management 1.0.0 → 1.1.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.
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