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 +4 -4
- data/.rubocop.yml +1 -0
- data/lib/berta/exclusions.rb +109 -0
- data/lib/berta/service.rb +15 -51
- data/lib/berta/version.rb +1 -1
- data/lib/berta/virtual_machine_handler.rb +17 -12
- data/lib/berta.rb +1 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0b948acea2bb242909ad1d4f48c7a63955fb26e4
|
4
|
+
data.tar.gz: 33ab8c9275003edea5335835ca89f680dd0fd2ed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d897e5502b897611794beb1e6ddbc29ca028171954ecf1ce8c548261c7055a0040550f925124a4cb6a1087138ca747abd715c948fcb46b9d4efa018d3e5e37d0
|
7
|
+
data.tar.gz: f3b22ce6b6eb4763503bbfe70476668bb100187a187da5facb82933da986f2b1bb41dc54c4b5bf72f5a49e7506cc71aa054e9b7d66b9acdfb290c7d5fc241040
|
data/.rubocop.yml
CHANGED
@@ -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
|
-
|
42
|
-
|
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
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
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
@@ -13,8 +13,9 @@ module Berta
|
|
13
13
|
@handle = vm
|
14
14
|
end
|
15
15
|
|
16
|
-
# Sets
|
17
|
-
# as integer.
|
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
|
-
|
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
|
39
|
+
# Return notified flag value from USER_TEMPLATE if it is set
|
37
40
|
# else nil.
|
38
41
|
#
|
39
|
-
# @return [Numeric] Time
|
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
|
48
|
-
#
|
49
|
-
#
|
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
|
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
|
-
#
|
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.
|
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-
|
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.
|
304
|
+
rubygems_version: 2.6.10
|
304
305
|
signing_key:
|
305
306
|
specification_version: 4
|
306
307
|
summary: Berta VM expiration tool
|