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.
- checksums.yaml +4 -4
 - data/README.md +9 -0
 - data/Rakefile +0 -0
 - data/app/controllers/api/v2/snapshots_controller.rb +107 -0
 - data/app/controllers/concerns/foreman/controller/parameters/snapshot.rb +15 -0
 - data/app/controllers/foreman_snapshot_management/snapshots_controller.rb +72 -54
 - data/app/models/concerns/fog_extensions/vsphere/snapshots/mock.rb +33 -0
 - data/app/models/concerns/fog_extensions/vsphere/snapshots/real.rb +43 -0
 - data/app/models/foreman_snapshot_management/snapshot.rb +80 -22
 - data/app/models/foreman_snapshot_management/vmware_extensions.rb +38 -6
 - data/app/overrides/hosts/add_tab_to_host_overview.rb +2 -12
 - data/app/views/api/v2/snapshots/base.json.rabl +3 -0
 - data/app/views/api/v2/snapshots/create.json.rabl +3 -0
 - data/app/views/api/v2/snapshots/destroy.json.rabl +3 -0
 - data/app/views/api/v2/snapshots/index.json.rabl +3 -0
 - data/app/views/api/v2/snapshots/main.json.rabl +9 -0
 - data/app/views/api/v2/snapshots/revert.json.rabl +3 -0
 - data/app/views/api/v2/snapshots/show.json.rabl +3 -0
 - data/app/views/api/v2/snapshots/update.json.rabl +3 -0
 - data/app/views/foreman_snapshot_management/hosts/_snapshots_tab.html.erb +3 -0
 - data/app/views/foreman_snapshot_management/hosts/_snapshots_tab_content.html.erb +7 -0
 - data/app/views/foreman_snapshot_management/snapshots/_index.html.erb +27 -16
 - data/config/routes.rb +17 -0
 - data/lib/foreman_snapshot_management/engine.rb +45 -11
 - data/lib/foreman_snapshot_management/version.rb +1 -1
 - data/test/controllers/api/v2/snapshots_test.rb +57 -0
 - data/test/controllers/foreman_snapshot_management/snapshots_controller_test.rb +85 -0
 - metadata +21 -6
 - data/app/helpers/foreman_snapshot_management/snapshotadministration_helper.rb +0 -72
 - 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:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: '048b5bbc495a00c7caf44380c5ee03ccd319e592'
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 7d331abbbb267a00c70485e8a74bb1e76d30f684
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 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 
     | 
    
         
            -
                   
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
                   
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
                   
     | 
| 
       26 
     | 
    
         
            -
                     
     | 
| 
       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 
     | 
    
         
            -
                   
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       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 
     | 
    
         
            -
                     
     | 
| 
      
 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 
     | 
    
         
            -
                   
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       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 
     | 
    
         
            -
                     
     | 
| 
      
 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 
     | 
    
         
            -
                   
     | 
| 
       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 
     | 
    
         
            -
                   
     | 
| 
       91 
     | 
    
         
            -
                     
     | 
| 
       92 
     | 
    
         
            -
                    render json: { errors:  
     | 
| 
      
 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 
     | 
    
         
            -
                   
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
             
     | 
| 
      
 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 
     | 
    
         
            -
                  #  
     | 
| 
       110 
     | 
    
         
            -
                  @snapshots = Snapshot.all_for_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 
     | 
| 
      
 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, : 
     | 
| 
      
 12 
     | 
    
         
            +
                attr_accessor :id, :raw_snapshot, :name, :description, :host_id, :parent, :create_time
         
     | 
| 
       10 
13 
     | 
    
         | 
| 
       11 
     | 
    
         
            -
                def self. 
     | 
| 
       12 
     | 
    
         
            -
                  snapshots 
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       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. 
     | 
| 
       19 
     | 
    
         
            -
                   
     | 
| 
       20 
     | 
    
         
            -
                   
     | 
| 
       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. 
     | 
| 
       26 
     | 
    
         
            -
                   
     | 
| 
      
 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  
     | 
| 
       30 
     | 
    
         
            -
                   
     | 
| 
      
 53 
     | 
    
         
            +
                def formatted_create_time()
         
     | 
| 
      
 54 
     | 
    
         
            +
                  create_time.strftime("%F %H:%M")
         
     | 
| 
       31 
55 
     | 
    
         
             
                end
         
     | 
| 
       32 
56 
     | 
    
         | 
| 
       33 
57 
     | 
    
         
             
                def persisted?
         
     | 
| 
       34 
     | 
    
         
            -
                   
     | 
| 
      
 58 
     | 
    
         
            +
                  self.id.present?
         
     | 
| 
       35 
59 
     | 
    
         
             
                end
         
     | 
| 
       36 
60 
     | 
    
         | 
| 
       37 
61 
     | 
    
         
             
                # host accessors
         
     | 
| 
       38 
62 
     | 
    
         
             
                def host
         
     | 
| 
       39 
     | 
    
         
            -
                  Host.find( 
     | 
| 
      
 63 
     | 
    
         
            +
                  Host.find(self.host_id)
         
     | 
| 
       40 
64 
     | 
    
         
             
                end
         
     | 
| 
       41 
65 
     | 
    
         | 
| 
       42 
66 
     | 
    
         
             
                def host=(host)
         
     | 
| 
       43 
     | 
    
         
            -
                   
     | 
| 
      
 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 
     | 
    
         
            -
                     
     | 
| 
      
 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 
     | 
    
         
            -
                     
     | 
| 
      
 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 =  
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
      
 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 
     | 
    
         
            -
                     
     | 
| 
      
 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 
     | 
    
         
            -
                 
     | 
| 
      
 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,  
     | 
| 
       16 
     | 
    
         
            -
                  client.remove_snapshot('snapshot' => snapshot, '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 
     | 
    
         
            -
                                  
     | 
| 
      
 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 
     | 
    
         
            -
                                  
     | 
| 
      
 11 
     | 
    
         
            +
                                 partial: 'foreman_snapshot_management/hosts/snapshots_tab_content')
         
     | 
| 
         @@ -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 
     | 
    
         
            -
                 
     | 
| 
       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 
     | 
    
         
            -
                      <%=  
     | 
| 
      
 14 
     | 
    
         
            +
                      <%= f.text_field :name, class: 'form-control' %>
         
     | 
| 
       26 
15 
     | 
    
         
             
                    </td>
         
     | 
| 
       27 
16 
     | 
    
         
             
                    <td>
         
     | 
| 
       28 
     | 
    
         
            -
                      <%=  
     | 
| 
      
 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:  
     | 
| 
       33 
     | 
    
         
            -
                        display_delete_if_authorized(hash_for_host_snapshot_path(host_id: @host, id:  
     | 
| 
      
 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>
         
     | 
    
        data/config/routes.rb
    CHANGED
    
    | 
         @@ -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/ 
     | 
| 
       8 
     | 
    
         
            -
                config.autoload_paths += Dir["#{config.root}/app/ 
     | 
| 
       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 : 
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
                       
     | 
| 
      
 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 
     | 
    
         
            -
                    #  
     | 
| 
       25 
     | 
    
         
            -
                    role ' 
     | 
| 
      
 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 
     | 
    
         
            -
                     
     | 
| 
      
 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
         
     | 
| 
         @@ -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. 
     | 
| 
      
 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- 
     | 
| 
      
 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/ 
     | 
| 
      
 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
         
     |