berta 1.3.0 → 1.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ddb138a3a440ced8f3cac19a172dc852553bf6d7
4
- data.tar.gz: d03578fdc338e243fa153094632a10e08f4e6925
3
+ metadata.gz: 0b948acea2bb242909ad1d4f48c7a63955fb26e4
4
+ data.tar.gz: 33ab8c9275003edea5335835ca89f680dd0fd2ed
5
5
  SHA512:
6
- metadata.gz: 5d39ec846445b8e28c9431aded6a925de3ecc61fb520e1f959964ee8ad917856761f7186573def0e85b9587d6785f860c7fbd944f2e5e617695965c23e2a627b
7
- data.tar.gz: 12b40d29cb3e5549fa9ad8299af378d5b9a9f8b05d4a8eb434b3f76e501237eff5a236c73cdef1588b189ad2478aeda1cb184305981eb9c8e31566540770c859
6
+ metadata.gz: d897e5502b897611794beb1e6ddbc29ca028171954ecf1ce8c548261c7055a0040550f925124a4cb6a1087138ca747abd715c948fcb46b9d4efa018d3e5e37d0
7
+ data.tar.gz: f3b22ce6b6eb4763503bbfe70476668bb100187a187da5facb82933da986f2b1bb41dc54c4b5bf72f5a49e7506cc71aa054e9b7d66b9acdfb290c7d5fc241040
data/.rubocop.yml CHANGED
@@ -16,6 +16,7 @@ Metrics/BlockLength:
16
16
  - 'spec/**/*.rb'
17
17
  - '*.gemspec'
18
18
  Metrics/AbcSize:
19
+ Max: 20
19
20
  Exclude:
20
21
  - 'lib/berta/cli.rb'
21
22
 
@@ -0,0 +1,109 @@
1
+ module Berta
2
+ # Class for Handeling berta exclusions
3
+ class Exclusions
4
+ # VM states that take resources
5
+ RESOURCE_STATES = %w(SUSPENDED POWEROFF CLONING).freeze
6
+ # Active state has some lcm states that should not expire
7
+ ACTIVE_STATE = 'ACTIVE'.freeze
8
+ # LCM states in which active state shouldn't expire
9
+ NON_RESOURCE_ACTIVE_LCM_STATES = %w(EPILOG SHUTDOWN STOP UNDEPLOY FAILURE).freeze
10
+
11
+ # Constructs Exclusions object.
12
+ #
13
+ # @param ids [Array<Numeric>] Ids of VM to exclude
14
+ # @param users [Array<String>] User names to exclude
15
+ # @param groups [Array<String>] Group names to exclude
16
+ # @param clusters [Array<OpenNebula::Cluster>] Clusters to exclude
17
+ def initialize(ids, users, groups, clusters)
18
+ @ids = ids
19
+ @users = users
20
+ @groups = groups
21
+ @clusters = clusters
22
+ log_exclusions
23
+ end
24
+
25
+ # Filters out excluded vms, and vms that doesn't take resources
26
+ #
27
+ # @param vmhs [Array<Berta::VirtualMachineHandler>] Array of VMs to filter
28
+ def filter!(vmhs)
29
+ filter_resources!(vmhs)
30
+ filter_ids!(vmhs)
31
+ filter_users!(vmhs)
32
+ filter_groups!(vmhs)
33
+ filter_clusters!(vmhs)
34
+ logger.debug "After excluding: #{vmhs.map { |vmh| vmh.handle.id }}"
35
+ vmhs
36
+ end
37
+
38
+ private
39
+
40
+ def log_exclusions
41
+ logger.debug "Excluded ids : #{@ids}"
42
+ logger.debug "Excluded users : #{@users}"
43
+ logger.debug "Excluded groups : #{@groups}"
44
+ logger.debug "Excluded clusters: #{@clusters.map { |cluster| cluster['NAME'] }}"
45
+ end
46
+
47
+ def excluded_id?(vmh)
48
+ @ids.find { |id| vmh.handle['ID'].to_i == id.to_i } if vmh.handle['ID'] && @ids
49
+ end
50
+
51
+ def excluded_user?(vmh)
52
+ @users.find { |user| vmh.handle['UNAME'] == user } if vmh.handle['UNAME'] && @users
53
+ end
54
+
55
+ def excluded_group?(vmh)
56
+ @groups.find { |group| vmh.handle['GNAME'] == group } if vmh.handle['GNAME'] && @groups
57
+ end
58
+
59
+ def excluded_cluster?(vmh)
60
+ vmhcid = latest_cluster_id(vmh)
61
+ @clusters.find { |cluster| vmhcid == cluster['ID'] } if vmhcid && @clusters
62
+ end
63
+
64
+ def takes_resources?(vmh)
65
+ return true if RESOURCE_STATES.any? { |state| vmh.handle.state_str == state }
66
+ true if vmh.handle.state_str == ACTIVE_STATE &&
67
+ NON_RESOURCE_ACTIVE_LCM_STATES.none? { |state| vmh.handle.lcm_state_str.include? state }
68
+ end
69
+
70
+ def filter_ids!(vmhs)
71
+ deleted, keep = vmhs.partition { |vmh| excluded_id?(vmh) }
72
+ logger.debug "Excluding based on IDs. Excluded IDs : #{deleted.map { |vmh| vmh.handle.id }}"
73
+ vmhs.replace(keep)
74
+ deleted
75
+ end
76
+
77
+ def filter_users!(vmhs)
78
+ deleted, keep = vmhs.partition { |vmh| excluded_user?(vmh) }
79
+ logger.debug "Excluding based on USERs. Excluded IDs : #{deleted.map { |vmh| vmh.handle.id }}"
80
+ vmhs.replace(keep)
81
+ deleted
82
+ end
83
+
84
+ def filter_groups!(vmhs)
85
+ deleted, keep = vmhs.partition { |vmh| excluded_group?(vmh) }
86
+ logger.debug "Excluding based on GROUPs. Excluded IDs : #{deleted.map { |vmh| vmh.handle.id }}"
87
+ vmhs.replace(keep)
88
+ deleted
89
+ end
90
+
91
+ def filter_clusters!(vmhs)
92
+ deleted, keep = vmhs.partition { |vmh| excluded_cluster?(vmh) }
93
+ logger.debug "Excluding based on CLUSTERs. Excluded IDs : #{deleted.map { |vmh| vmh.handle.id }}"
94
+ vmhs.replace(keep)
95
+ deleted
96
+ end
97
+
98
+ def filter_resources!(vmhs)
99
+ keep, deleted = vmhs.partition { |vmh| takes_resources?(vmh) }
100
+ logger.debug "Excluding based on RESOURCE_STATEs. Excluded IDs: #{deleted.map { |vmh| vmh.handle.id }}"
101
+ vmhs.replace(keep)
102
+ deleted
103
+ end
104
+
105
+ def latest_cluster_id(vmh)
106
+ vmh.handle['HISTORY_RECORDS/HISTORY[last()]/CID']
107
+ end
108
+ end
109
+ end
data/lib/berta/service.rb CHANGED
@@ -3,13 +3,6 @@ require 'opennebula'
3
3
  module Berta
4
4
  # Berta service for communication with OpenNebula
5
5
  class Service
6
- # VM states that take resources
7
- RESOURCE_STATES = %w(SUSPENDED POWEROFF CLONING).freeze
8
- # Active state has some lcm states that should not expire
9
- ACTIVE_STATE = 'ACTIVE'.freeze
10
- # LCM states in which active state shouldn't expire
11
- NON_RESOURCE_ACTIVE_LCM_STATES = %w(EPILOG SHUTDOWN STOP UNDEPLOY FAILURE).freeze
12
-
13
6
  attr_reader :endpoint
14
7
  attr_reader :client
15
8
 
@@ -35,11 +28,13 @@ module Berta
35
28
  # @raise [Berta::Errors::OpenNebula::ResourceStateError]
36
29
  # @raise [Berta::Errors::OpenNebula::ResourceRetrievalError]
37
30
  def running_vms
38
- logger.debug 'Fetching vms'
39
31
  vm_pool = OpenNebula::VirtualMachinePool.new(client)
40
32
  Berta::Utils::OpenNebula::Helper.handle_error { vm_pool.info_all }
41
- vm_pool.map { |vm| Berta::VirtualMachineHandler.new(vm) }
42
- .delete_if { |vmh| excluded?(vmh) || !takes_resources?(vmh) }
33
+ logger.debug "Fetched vms: #{vm_pool.map(&:id)}"
34
+ Berta::Exclusions.new(Berta::Settings.exclude.ids,
35
+ Berta::Settings.exclude.users,
36
+ Berta::Settings.exclude.groups,
37
+ excluded_clusters).filter!(vm_pool.map { |vm| Berta::VirtualMachineHandler.new(vm) })
43
38
  end
44
39
 
45
40
  # Fetch users from OpenNebula
@@ -51,9 +46,9 @@ module Berta
51
46
  # @raise [Berta::Errors::OpenNebula::ResourceStateError]
52
47
  # @raise [Berta::Errors::OpenNebula::ResourceRetrievalError]
53
48
  def users
54
- logger.debug 'Fetching users'
55
49
  user_pool = OpenNebula::UserPool.new(client)
56
50
  Berta::Utils::OpenNebula::Helper.handle_error { user_pool.info }
51
+ logger.debug "Fetched users: #{user_pool.map(&:id)}"
57
52
  user_pool
58
53
  end
59
54
 
@@ -67,54 +62,23 @@ module Berta
67
62
  # @raise [Berta::Errors::OpenNebula::ResourceRetrievalError]
68
63
  def clusters
69
64
  return @cached_clusters if @cached_clusters
70
- logger.debug 'Fetching clusters'
71
65
  cluster_pool = OpenNebula::ClusterPool.new(client)
72
66
  Berta::Utils::OpenNebula::Helper.handle_error { cluster_pool.info }
67
+ logger.debug "Fetched clusters: #{cluster_pool.map(&:id)}"
73
68
  @cached_clusters = cluster_pool
74
69
  cluster_pool
75
70
  end
76
71
 
77
72
  private
78
73
 
79
- def excluded?(vmh)
80
- excluded_id?(vmh) ||
81
- excluded_user?(vmh) ||
82
- excluded_group?(vmh) ||
83
- excluded_cluster?(vmh)
84
- end
85
-
86
- def excluded_id?(vmh)
87
- Berta::Settings.exclude.ids.find { |id| vmh.handle.id == id } \
88
- if vmh.handle.id && Berta::Settings.exclude.ids
89
- end
90
-
91
- def excluded_user?(vmh)
92
- Berta::Settings.exclude.users.find { |user| vmh.handle['UNAME'] == user } \
93
- if vmh.handle['UNAME'] && Berta::Settings.exclude.users
94
- end
95
-
96
- def excluded_group?(vmh)
97
- Berta::Settings.exclude.groups.find { |group| vmh.handle['GNAME'] == group } \
98
- if vmh.handle['GNAME'] && Berta::Settings.exclude.groups
99
- end
100
-
101
- def excluded_cluster?(vmh)
102
- return unless Berta::Settings.exclude.clusters
103
- vmcid = latest_cluster_id(vmh)
104
- vmcluster = clusters.find { |cluster| cluster['ID'] == vmcid }
105
- return unless vmcluster
106
- Berta::Settings.exclude.clusters.find { |name| vmcluster['NAME'] == name } \
107
- if vmcluster['NAME']
108
- end
109
-
110
- def latest_cluster_id(vmh)
111
- vmh.handle['HISTORY_RECORDS/HISTORY[last()]/CID']
112
- end
113
-
114
- def takes_resources?(vmh)
115
- return true if RESOURCE_STATES.any? { |state| vmh.handle.state_str == state }
116
- return true if vmh.handle.state_str == ACTIVE_STATE &&
117
- NON_RESOURCE_ACTIVE_LCM_STATES.none? { |state| vmh.handle.lcm_state_str.include? state }
74
+ def excluded_clusters
75
+ excluded = []
76
+ if Berta::Settings.exclude.clusters
77
+ clusters.each do |cluster|
78
+ excluded << cluster if Berta::Settings.exclude.clusters.find { |cname| cname == cluster['NAME'] }
79
+ end
80
+ end
81
+ excluded
118
82
  end
119
83
  end
120
84
  end
data/lib/berta/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Berta
2
- VERSION = '1.3.0'.freeze
2
+ VERSION = '1.4.0'.freeze
3
3
  end
@@ -13,8 +13,9 @@ module Berta
13
13
  @handle = vm
14
14
  end
15
15
 
16
- # Sets NOTIFIED value in USER_TEMPLATE to current time
17
- # as integer. After updating notified value
16
+ # Sets notified flag value in USER_TEMPLATE to default expiration
17
+ # time as integer. If VM has no default expiration nothing will
18
+ # be updated. After updating notified value
18
19
  # fetches data from opennebula database.
19
20
  #
20
21
  # @note This method modifies OpenNebula database
@@ -24,7 +25,9 @@ module Berta
24
25
  # @raise [Berta::Errors::OpenNebula::ResourceStateError]
25
26
  # @raise [Berta::Errors::OpenNebula::ResourceRetrievalError]
26
27
  def update_notified
27
- notify_time = Time.now
28
+ exp = default_expiration
29
+ return unless exp
30
+ notify_time = exp.time
28
31
  logger.debug "Setting notified flag of VM with id #{handle['ID']} to #{notify_time}"
29
32
  return if Berta::Settings['dry-run']
30
33
  Berta::Utils::OpenNebula::Helper.handle_error do
@@ -33,27 +36,26 @@ module Berta
33
36
  end
34
37
  end
35
38
 
36
- # Return NOTIFIED value from USER_TEMPLATE if it is set
39
+ # Return notified flag value from USER_TEMPLATE if it is set
37
40
  # else nil.
38
41
  #
39
- # @return [Numeric] Time when notified was set else nil.
40
- # Time is in UNIX epoch time format.
42
+ # @return [Numeric] Time of expiration that VM was notified about
41
43
  def notified
42
44
  time = handle["USER_TEMPLATE/#{NOTIFIED_FLAG}"]
43
45
  time.to_i if time
44
46
  end
45
47
 
46
48
  # Determines if VM meets criteria to be notified.
47
- # To be notified, VM musn't be notified and
48
- # must have expiration with valid expiration
49
- # action in notification interval.
49
+ # To be notified, VM musn't have the same notification
50
+ # time as default expiration time and must be in
51
+ # notification interval.
50
52
  #
51
53
  # @return [Boolean] If this vm should be notified.
52
54
  # True if vm should be notified else false.
53
55
  def should_notify?
54
- return false if notified
55
56
  expiration = default_expiration
56
57
  return false unless expiration
58
+ return false if notified == expiration.time.to_i
57
59
  expiration.in_notification_interval?
58
60
  end
59
61
 
@@ -66,7 +68,8 @@ module Berta
66
68
  template = ''
67
69
  exps.each { |exp| template += exp.template }
68
70
  return if template == ''
69
- logger.debug "Setting multiple expirations on vm with id=#{handle['ID']} :\n#{template}"
71
+ logger.debug \
72
+ "Setting expirations on vm with id=#{handle['ID']} usr=#{handle['UNAME']} grp=#{handle['GNAME']} : #{template.delete("\n ")}"
70
73
  return if Berta::Settings['dry-run']
71
74
  Berta::Utils::OpenNebula::Helper.handle_error do
72
75
  handle.update(template, true)
@@ -96,7 +99,9 @@ module Berta
96
99
  .min { |exp| exp.time.to_i }
97
100
  end
98
101
 
99
- # TODO
102
+ # Return first available SCHED_ACTION/ID
103
+ #
104
+ # @return [Numeric] Next sched action id
100
105
  def next_expiration_id
101
106
  elems = handle.retrieve_elements('USER_TEMPLATE/SCHED_ACTION/ID')
102
107
  return 0 unless elems
data/lib/berta.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # Main Berta module
2
2
  module Berta
3
3
  autoload :Service, 'berta/service'
4
+ autoload :Exclusions, 'berta/exclusions'
4
5
  autoload :VirtualMachineHandler, 'berta/virtual_machine_handler'
5
6
  autoload :ExpirationManager, 'berta/expiration_manager'
6
7
  autoload :NotificationManager, 'berta/notification_manager'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: berta
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dusan Baran
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-14 00:00:00.000000000 Z
11
+ date: 2017-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -271,6 +271,7 @@ files:
271
271
  - lib/berta/errors/opennebula/stub_error.rb
272
272
  - lib/berta/errors/opennebula/user_not_authorized_error.rb
273
273
  - lib/berta/errors/standard_error.rb
274
+ - lib/berta/exclusions.rb
274
275
  - lib/berta/expiration_manager.rb
275
276
  - lib/berta/notification_manager.rb
276
277
  - lib/berta/service.rb
@@ -300,7 +301,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
300
301
  version: '0'
301
302
  requirements: []
302
303
  rubyforge_project:
303
- rubygems_version: 2.6.8
304
+ rubygems_version: 2.6.10
304
305
  signing_key:
305
306
  specification_version: 4
306
307
  summary: Berta VM expiration tool