berta 1.4.0 → 1.4.1
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/lib/berta/cli.rb +14 -14
- data/lib/berta/command_executor.rb +18 -3
- data/lib/berta/entities/expiration.rb +7 -2
- data/lib/berta/exclusions.rb +2 -2
- data/lib/berta/service.rb +18 -7
- data/lib/berta/user_handler.rb +52 -0
- data/lib/berta/version.rb +1 -1
- data/lib/berta/virtual_machine_handler.rb +55 -32
- data/lib/berta.rb +1 -2
- metadata +4 -5
- data/lib/berta/expiration_manager.rb +0 -43
- data/lib/berta/notification_manager.rb +0 -100
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1ce1338b8020499e9cae1605ddf66c0dad404aae
|
4
|
+
data.tar.gz: dea58173ca736a372e9b6a30f3b08a29efa282b7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db63fd0e325e176bd390db3481f48b063077d21e5b0edd6db0d00498cd48a9b0b65a46fc4b205da9e59a2c189994fe39450809be103e4bd60247d4be0fc1fba5
|
7
|
+
data.tar.gz: 6e12df6f7cec8f294ed0893528208a317ac40695e51d12d765fdf7e70961234ab081e9449e08c8da4bade3f2314e86c2bb642dd81dc44ddb8e05711f94daf326
|
data/lib/berta/cli.rb
CHANGED
@@ -14,54 +14,54 @@ module Berta
|
|
14
14
|
end
|
15
15
|
|
16
16
|
class_option :'opennebula-secret',
|
17
|
-
default: safe_fetch(%w
|
17
|
+
default: safe_fetch(%w[opennebula secret]),
|
18
18
|
type: :string
|
19
19
|
class_option :'opennebula-endpoint',
|
20
|
-
default: safe_fetch(%w
|
20
|
+
default: safe_fetch(%w[opennebula endpoint]),
|
21
21
|
type: :string
|
22
22
|
class_option :'expiration-offset',
|
23
23
|
required: true,
|
24
|
-
default: safe_fetch(%w
|
24
|
+
default: safe_fetch(%w[expiration offset]),
|
25
25
|
type: :string
|
26
26
|
class_option :'expiration-action',
|
27
27
|
required: true,
|
28
|
-
default: safe_fetch(%w
|
28
|
+
default: safe_fetch(%w[expiration action]),
|
29
29
|
type: :string
|
30
30
|
class_option :'notification-deadline',
|
31
31
|
required: true,
|
32
|
-
default: safe_fetch(%w
|
32
|
+
default: safe_fetch(%w[notification deadline]),
|
33
33
|
type: :string
|
34
34
|
class_option :'exclude-ids',
|
35
|
-
default: safe_fetch(%w
|
35
|
+
default: safe_fetch(%w[exclude ids]),
|
36
36
|
type: :array
|
37
37
|
class_option :'exclude-users',
|
38
|
-
default: safe_fetch(%w
|
38
|
+
default: safe_fetch(%w[exclude users]),
|
39
39
|
type: :array
|
40
40
|
class_option :'exclude-groups',
|
41
|
-
default: safe_fetch(%w
|
41
|
+
default: safe_fetch(%w[exclude groups]),
|
42
42
|
type: :array
|
43
43
|
class_option :'exclude-clusters',
|
44
|
-
default: safe_fetch(%w
|
44
|
+
default: safe_fetch(%w[exclude clusters]),
|
45
45
|
type: :array
|
46
46
|
class_option :'dry-run',
|
47
|
-
default: safe_fetch(%w
|
47
|
+
default: safe_fetch(%w[dry-run]),
|
48
48
|
type: :boolean
|
49
49
|
class_option :'logging-file',
|
50
|
-
default: safe_fetch(%w
|
50
|
+
default: safe_fetch(%w[logging file]),
|
51
51
|
type: :string
|
52
52
|
class_option :'logging-level',
|
53
53
|
required: true,
|
54
|
-
default: safe_fetch(%w
|
54
|
+
default: safe_fetch(%w[logging level]),
|
55
55
|
type: :string
|
56
56
|
class_option :debug,
|
57
|
-
default: safe_fetch(%w
|
57
|
+
default: safe_fetch(%w[debug]),
|
58
58
|
type: :boolean
|
59
59
|
|
60
60
|
desc 'cleanup', 'Task that sets all expiration to all vms and notifies users'
|
61
61
|
def cleanup
|
62
62
|
initialize_configuration(options)
|
63
63
|
initialize_logger(options)
|
64
|
-
Berta::CommandExecutor.cleanup
|
64
|
+
Berta::CommandExecutor.new.cleanup
|
65
65
|
end
|
66
66
|
|
67
67
|
desc 'version', 'Prints berta version'
|
@@ -1,16 +1,31 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'tilt'
|
3
|
+
|
1
4
|
module Berta
|
2
5
|
# Class for executing main berta commands
|
3
6
|
class CommandExecutor
|
7
|
+
def initialize
|
8
|
+
email_file = 'email.erb'.freeze
|
9
|
+
email_template_path = "#{File.dirname(__FILE__)}/../../config/#{email_file}"
|
10
|
+
email_template_path = "/etc/berta/#{email_file}" \
|
11
|
+
if File.exist?("/etc/berta/#{email_file}")
|
12
|
+
email_template_path = "#{ENV['HOME']}/.berta/#{email_file}" \
|
13
|
+
if File.exist?("#{ENV['HOME']}/.berta/#{email_file}")
|
14
|
+
@email_template = Tilt.new(email_template_path)
|
15
|
+
end
|
16
|
+
|
4
17
|
# Function that performs clean up operation.
|
5
18
|
# Connects to opennebula database,
|
6
19
|
# runs expiration update process and
|
7
20
|
# notifies users about upcoming expirations.
|
8
|
-
def
|
21
|
+
def cleanup
|
9
22
|
service = Berta::Service.new(Berta::Settings['opennebula']['secret'],
|
10
23
|
Berta::Settings['opennebula']['endpoint'])
|
11
24
|
vms = service.running_vms
|
12
|
-
|
13
|
-
|
25
|
+
users = service.users
|
26
|
+
vms.each(&:update)
|
27
|
+
Mail.defaults { delivery_method :sendmail }
|
28
|
+
users.each { |user| user.notify(service.user_vms(user), @email_template) }
|
14
29
|
rescue Berta::Errors::BackendError => e
|
15
30
|
logger.error e.message
|
16
31
|
end
|
@@ -20,9 +20,9 @@ module Berta
|
|
20
20
|
# @raise [Berta::Errors::Entities::InvalidEntityXMLError] If xml is not in correct format
|
21
21
|
def self.check_xml!(xml)
|
22
22
|
raise Berta::Errors::Entities::InvalidEntityXMLError, 'wrong enxpiration xml recieved' \
|
23
|
-
unless %w
|
23
|
+
unless %w[ID
|
24
24
|
ACTION
|
25
|
-
TIME
|
25
|
+
TIME].all? { |path| xml.has_elements? path }
|
26
26
|
end
|
27
27
|
|
28
28
|
# Creates expiration class instance from given arguments.
|
@@ -77,6 +77,11 @@ module Berta
|
|
77
77
|
def default_action?
|
78
78
|
action == Berta::Settings.expiration.action
|
79
79
|
end
|
80
|
+
|
81
|
+
# TODO: doc
|
82
|
+
def ==(other)
|
83
|
+
id == other.id && action == other.action && time == other.time
|
84
|
+
end
|
80
85
|
end
|
81
86
|
end
|
82
87
|
end
|
data/lib/berta/exclusions.rb
CHANGED
@@ -2,11 +2,11 @@ module Berta
|
|
2
2
|
# Class for Handeling berta exclusions
|
3
3
|
class Exclusions
|
4
4
|
# VM states that take resources
|
5
|
-
RESOURCE_STATES = %w
|
5
|
+
RESOURCE_STATES = %w[SUSPENDED POWEROFF CLONING].freeze
|
6
6
|
# Active state has some lcm states that should not expire
|
7
7
|
ACTIVE_STATE = 'ACTIVE'.freeze
|
8
8
|
# LCM states in which active state shouldn't expire
|
9
|
-
NON_RESOURCE_ACTIVE_LCM_STATES = %w
|
9
|
+
NON_RESOURCE_ACTIVE_LCM_STATES = %w[EPILOG SHUTDOWN STOP UNDEPLOY FAILURE].freeze
|
10
10
|
|
11
11
|
# Constructs Exclusions object.
|
12
12
|
#
|
data/lib/berta/service.rb
CHANGED
@@ -20,7 +20,7 @@ module Berta
|
|
20
20
|
# Fetch running vms from OpenNebula and filter out vms that
|
21
21
|
# take no resources.
|
22
22
|
#
|
23
|
-
# @return [Berta::VirtualMachineHandler] Virtual machines
|
23
|
+
# @return [Array<Berta::VirtualMachineHandler>] Virtual machines
|
24
24
|
# running on OpenNebula
|
25
25
|
# @raise [Berta::Errors::OpenNebula::AuthenticationError]
|
26
26
|
# @raise [Berta::Errors::OpenNebula::UserNotAuthorizedError]
|
@@ -28,18 +28,20 @@ module Berta
|
|
28
28
|
# @raise [Berta::Errors::OpenNebula::ResourceStateError]
|
29
29
|
# @raise [Berta::Errors::OpenNebula::ResourceRetrievalError]
|
30
30
|
def running_vms
|
31
|
+
return @cached_vms if @cached_vms
|
31
32
|
vm_pool = OpenNebula::VirtualMachinePool.new(client)
|
32
33
|
Berta::Utils::OpenNebula::Helper.handle_error { vm_pool.info_all }
|
33
34
|
logger.debug "Fetched vms: #{vm_pool.map(&:id)}"
|
34
|
-
Berta::Exclusions.new(Berta::Settings.exclude.ids,
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
@cached_vms = Berta::Exclusions.new(Berta::Settings.exclude.ids,
|
36
|
+
Berta::Settings.exclude.users,
|
37
|
+
Berta::Settings.exclude.groups,
|
38
|
+
excluded_clusters).filter!(vm_pool.map { |vm| Berta::VirtualMachineHandler.new(vm) })
|
39
|
+
@cached_vms
|
38
40
|
end
|
39
41
|
|
40
42
|
# Fetch users from OpenNebula
|
41
43
|
#
|
42
|
-
# @return [OpenNebula::
|
44
|
+
# @return [Array<OpenNebula::UserHandler>] Users on OpenNebula
|
43
45
|
# @raise [Berta::Errors::OpenNebula::AuthenticationError]
|
44
46
|
# @raise [Berta::Errors::OpenNebula::UserNotAuthorizedError]
|
45
47
|
# @raise [Berta::Errors::OpenNebula::ResourceNotFoundError]
|
@@ -49,7 +51,16 @@ module Berta
|
|
49
51
|
user_pool = OpenNebula::UserPool.new(client)
|
50
52
|
Berta::Utils::OpenNebula::Helper.handle_error { user_pool.info }
|
51
53
|
logger.debug "Fetched users: #{user_pool.map(&:id)}"
|
52
|
-
user_pool
|
54
|
+
user_pool.map { |user| Berta::UserHandler.new(user) }
|
55
|
+
end
|
56
|
+
|
57
|
+
# Return vms that belong to given user
|
58
|
+
#
|
59
|
+
# @note calls running_vms
|
60
|
+
# @param user [Berta::UserHandler] User to find vms for
|
61
|
+
# @return [Array<Berta::VirtualMachineHandler>] VMs that belong to given user
|
62
|
+
def user_vms(user)
|
63
|
+
running_vms.keep_if { |vm| vm.handle['UID'] == user.handle['ID'] }
|
53
64
|
end
|
54
65
|
|
55
66
|
# Fetch clusters from OpenNebula
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'mail'
|
2
|
+
require 'erb'
|
3
|
+
require 'tilt'
|
4
|
+
|
5
|
+
module Berta
|
6
|
+
# Class for handeling user methods
|
7
|
+
class UserHandler
|
8
|
+
attr_reader :handle
|
9
|
+
|
10
|
+
# Initializes UserHandler object
|
11
|
+
#
|
12
|
+
# @param user [OpenNebula::User] User that will this
|
13
|
+
# handle use
|
14
|
+
def initialize(user)
|
15
|
+
@handle = user
|
16
|
+
end
|
17
|
+
|
18
|
+
# Notifies user about all vms that are in notification interval
|
19
|
+
#
|
20
|
+
# @param user_vms [Array<Berta::VirtualMachineHandler>] All vms that belong to
|
21
|
+
# this user
|
22
|
+
# @param email_template [Tilt::ERBTemplate] Email template
|
23
|
+
def notify(user_vms, email_template)
|
24
|
+
to_notify = user_vms.keep_if(&:should_notify?)
|
25
|
+
return if to_notify.empty?
|
26
|
+
send_notification(to_notify, email_template)
|
27
|
+
user_vms.each(&:update_notified)
|
28
|
+
rescue ArgumentError, Berta::Errors::Entities::NoUserEmailError => e
|
29
|
+
logger.error e.message
|
30
|
+
end
|
31
|
+
|
32
|
+
def send_notification(user_vms, email_template)
|
33
|
+
user_email = handle['TEMPLATE/EMAIL']
|
34
|
+
user_name = handle['NAME']
|
35
|
+
raise Berta::Errors::Entities::NoUserEmailError, "User: #{user_name} with id: #{handle['ID']} has no email set" \
|
36
|
+
unless user_email
|
37
|
+
email_text = email_template.render(Hash, user_email: user_email, user_name: user_name, vms: vms_data(user_vms))
|
38
|
+
logger.debug "Sending mail to user: #{user_name} with email: #{user_email}:\n#{email_text}"
|
39
|
+
Mail.new(email_text).deliver unless Berta::Settings['dry-run']
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def vms_data(vms)
|
45
|
+
vms.map do |vm|
|
46
|
+
{ id: vm.handle['ID'],
|
47
|
+
name: vm.handle['NAME'],
|
48
|
+
expiration: vm.default_expiration.time.to_i }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/berta/version.rb
CHANGED
@@ -7,12 +7,24 @@ module Berta
|
|
7
7
|
|
8
8
|
# Constructs Virtual machine handler from given vm.
|
9
9
|
#
|
10
|
-
# @param vm [
|
10
|
+
# @param vm [OpenNebula::VirtualMachine] VM that will
|
11
11
|
# this handler use.
|
12
12
|
def initialize(vm)
|
13
13
|
@handle = vm
|
14
14
|
end
|
15
15
|
|
16
|
+
# Updates vms expirations. That means it adds default
|
17
|
+
# expiration if vm has no default expiration. If VM has
|
18
|
+
# invalid expiration it will be deleted. Other expirations
|
19
|
+
# are kept.
|
20
|
+
def update
|
21
|
+
exps = expirations.keep_if(&:in_expiration_interval?)
|
22
|
+
exps << next_expiration unless default_expiration
|
23
|
+
update_expirations(exps) unless exps == expirations
|
24
|
+
rescue Berta::Errors::BackendError => e
|
25
|
+
logger.error "#{e.message} on vm with id #{vm.handle['ID']}"
|
26
|
+
end
|
27
|
+
|
16
28
|
# Sets notified flag value in USER_TEMPLATE to default expiration
|
17
29
|
# time as integer. If VM has no default expiration nothing will
|
18
30
|
# be updated. After updating notified value
|
@@ -36,15 +48,6 @@ module Berta
|
|
36
48
|
end
|
37
49
|
end
|
38
50
|
|
39
|
-
# Return notified flag value from USER_TEMPLATE if it is set
|
40
|
-
# else nil.
|
41
|
-
#
|
42
|
-
# @return [Numeric] Time of expiration that VM was notified about
|
43
|
-
def notified
|
44
|
-
time = handle["USER_TEMPLATE/#{NOTIFIED_FLAG}"]
|
45
|
-
time.to_i if time
|
46
|
-
end
|
47
|
-
|
48
51
|
# Determines if VM meets criteria to be notified.
|
49
52
|
# To be notified, VM musn't have the same notification
|
50
53
|
# time as default expiration time and must be in
|
@@ -59,6 +62,39 @@ module Berta
|
|
59
62
|
expiration.in_notification_interval?
|
60
63
|
end
|
61
64
|
|
65
|
+
# Return default expiration, that means expiration with
|
66
|
+
# default expiration action that is in expiration offset interval
|
67
|
+
# and is closes to current date.
|
68
|
+
#
|
69
|
+
# @return [Berta::Entities::Expiration] Nearest default expiration else nil
|
70
|
+
def default_expiration
|
71
|
+
expirations
|
72
|
+
.find_all { |exp| exp.default_action? && exp.in_expiration_interval? }
|
73
|
+
.min { |exp| exp.time.to_i }
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns array of expirations on vm. Expirations are
|
77
|
+
# classes from USER_TEMPLATE/SCHED_ACTION.
|
78
|
+
#
|
79
|
+
# @return [Array<Berta::Entities::Expiration>] All expirations on vm
|
80
|
+
def expirations
|
81
|
+
exps = []
|
82
|
+
handle.each('USER_TEMPLATE/SCHED_ACTION') \
|
83
|
+
{ |saxml| exps.push(Berta::Entities::Expiration.from_xml(saxml)) }
|
84
|
+
exps
|
85
|
+
end
|
86
|
+
|
87
|
+
# Return notified flag value from USER_TEMPLATE if it is set
|
88
|
+
# else nil.
|
89
|
+
#
|
90
|
+
# @return [Numeric] Time of expiration that VM was notified about
|
91
|
+
def notified
|
92
|
+
time = handle["USER_TEMPLATE/#{NOTIFIED_FLAG}"]
|
93
|
+
time.to_i if time
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
62
98
|
# Sets array of expirations to vm, rewrites all old ones.
|
63
99
|
# Receiving empty array wont change anything.
|
64
100
|
#
|
@@ -77,28 +113,6 @@ module Berta
|
|
77
113
|
end
|
78
114
|
end
|
79
115
|
|
80
|
-
# Returns array of expirations on vm. Expirations are
|
81
|
-
# classes from USER_TEMPLATE/SCHED_ACTION.
|
82
|
-
#
|
83
|
-
# @return [Array<Berta::Entities::Expiration>] All expirations on vm
|
84
|
-
def expirations
|
85
|
-
exps = []
|
86
|
-
handle.each('USER_TEMPLATE/SCHED_ACTION') \
|
87
|
-
{ |saxml| exps.push(Berta::Entities::Expiration.from_xml(saxml)) }
|
88
|
-
exps
|
89
|
-
end
|
90
|
-
|
91
|
-
# Return default expiration, that means expiration with
|
92
|
-
# default expiration action that is in expiration offset interval
|
93
|
-
# and is closes to current date.
|
94
|
-
#
|
95
|
-
# @return [Berta::Entities::Expiration] Nearest default expiration else nil
|
96
|
-
def default_expiration
|
97
|
-
expirations
|
98
|
-
.find_all { |exp| exp.default_action? && exp.in_expiration_interval? }
|
99
|
-
.min { |exp| exp.time.to_i }
|
100
|
-
end
|
101
|
-
|
102
116
|
# Return first available SCHED_ACTION/ID
|
103
117
|
#
|
104
118
|
# @return [Numeric] Next sched action id
|
@@ -107,5 +121,14 @@ module Berta
|
|
107
121
|
return 0 unless elems
|
108
122
|
elems.to_a.max.to_i + 1
|
109
123
|
end
|
124
|
+
|
125
|
+
# Return default expiration that would be next for this vm
|
126
|
+
#
|
127
|
+
# @return [Berta::Entities::Expiration] Next expiration for this vm
|
128
|
+
def next_expiration
|
129
|
+
Berta::Entities::Expiration.new(next_expiration_id,
|
130
|
+
Time.now.to_i + Berta::Settings.expiration_offset,
|
131
|
+
Berta::Settings.expiration.action)
|
132
|
+
end
|
110
133
|
end
|
111
134
|
end
|
data/lib/berta.rb
CHANGED
@@ -3,8 +3,7 @@ module Berta
|
|
3
3
|
autoload :Service, 'berta/service'
|
4
4
|
autoload :Exclusions, 'berta/exclusions'
|
5
5
|
autoload :VirtualMachineHandler, 'berta/virtual_machine_handler'
|
6
|
-
autoload :
|
7
|
-
autoload :NotificationManager, 'berta/notification_manager'
|
6
|
+
autoload :UserHandler, 'berta/user_handler'
|
8
7
|
autoload :CommandExecutor, 'berta/command_executor'
|
9
8
|
autoload :CLI, 'berta/cli'
|
10
9
|
autoload :Errors, 'berta/errors'
|
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.
|
4
|
+
version: 1.4.1
|
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-
|
11
|
+
date: 2017-05-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -272,10 +272,9 @@ files:
|
|
272
272
|
- lib/berta/errors/opennebula/user_not_authorized_error.rb
|
273
273
|
- lib/berta/errors/standard_error.rb
|
274
274
|
- lib/berta/exclusions.rb
|
275
|
-
- lib/berta/expiration_manager.rb
|
276
|
-
- lib/berta/notification_manager.rb
|
277
275
|
- lib/berta/service.rb
|
278
276
|
- lib/berta/settings.rb
|
277
|
+
- lib/berta/user_handler.rb
|
279
278
|
- lib/berta/utils.rb
|
280
279
|
- lib/berta/utils/opennebula.rb
|
281
280
|
- lib/berta/utils/opennebula/helper.rb
|
@@ -301,7 +300,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
301
300
|
version: '0'
|
302
301
|
requirements: []
|
303
302
|
rubyforge_project:
|
304
|
-
rubygems_version: 2.6.
|
303
|
+
rubygems_version: 2.6.11
|
305
304
|
signing_key:
|
306
305
|
specification_version: 4
|
307
306
|
summary: Berta VM expiration tool
|
@@ -1,43 +0,0 @@
|
|
1
|
-
module Berta
|
2
|
-
# Class for managing expiration dates on vms
|
3
|
-
class ExpirationManager
|
4
|
-
# Update all expirations on vm, removes invalid expirations
|
5
|
-
# and if needed will set default expiration date.
|
6
|
-
#
|
7
|
-
# @param vms [Array<Berta::VirtualMachineHandler>] Virtual machines
|
8
|
-
# to update expiration on.
|
9
|
-
def update_expirations(vms)
|
10
|
-
vms.each do |vm|
|
11
|
-
begin
|
12
|
-
vm.update_expirations(add_default_expiration(vm, remove_invalid_expirations(vm.expirations)))
|
13
|
-
rescue Berta::Errors::BackendError => e
|
14
|
-
logger.error "#{e.message}\n\tOn vm with id #{vm.handle['ID']}"
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
# Removes invalid expirations from array of expirations.
|
20
|
-
# Invalid expirations are expirations that are planned
|
21
|
-
# later than expiration offset value.
|
22
|
-
#
|
23
|
-
# @param exps [Array<Berta::Entities::Expiration>] Expirations to filter
|
24
|
-
# @return [Array<Berta::Entities::Expiration>] Filtered expirations
|
25
|
-
def remove_invalid_expirations(exps)
|
26
|
-
exps.keep_if(&:in_expiration_interval?)
|
27
|
-
end
|
28
|
-
|
29
|
-
# Adds default vm expiration into given array of expirations
|
30
|
-
# assuming that array of expirations are expirations of given vm.
|
31
|
-
# If vm already has default expiration nothing will be changed.
|
32
|
-
#
|
33
|
-
# @param vm [Berta::VirtualMachineHandler] VM with or without default expiration
|
34
|
-
# @param exps [Array<Berta::Entities::Expiration>] VMs expirations to modify
|
35
|
-
# @return Expirations with default expiration
|
36
|
-
def add_default_expiration(vm, exps)
|
37
|
-
return [] if vm.default_expiration
|
38
|
-
exps << Berta::Entities::Expiration.new(vm.next_expiration_id,
|
39
|
-
Time.now.to_i + Berta::Settings.expiration_offset,
|
40
|
-
Berta::Settings.expiration.action)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
@@ -1,100 +0,0 @@
|
|
1
|
-
require 'mail'
|
2
|
-
require 'erb'
|
3
|
-
require 'tilt'
|
4
|
-
|
5
|
-
module Berta
|
6
|
-
# Class for managing notifications, setting and sending them
|
7
|
-
class NotificationManager
|
8
|
-
attr_reader :service, :email_template
|
9
|
-
|
10
|
-
# Creates NotificationManager object with given service.
|
11
|
-
# Notification manager needs service for fetching user
|
12
|
-
# data from opennebula database. Also initializes
|
13
|
-
# email template object.
|
14
|
-
#
|
15
|
-
# @param service [Berta::Service] Service that will be used
|
16
|
-
# for fetching data.
|
17
|
-
def initialize(service)
|
18
|
-
@service = service
|
19
|
-
email_file = 'email.erb'.freeze
|
20
|
-
email_template_path = "#{File.dirname(__FILE__)}/../../config/#{email_file}"
|
21
|
-
email_template_path = "/etc/berta/#{email_file}" \
|
22
|
-
if File.exist?("/etc/berta/#{email_file}")
|
23
|
-
email_template_path = "#{ENV['HOME']}/.berta/#{email_file}" \
|
24
|
-
if File.exist?("#{ENV['HOME']}/.berta/#{email_file}")
|
25
|
-
@email_template = Tilt.new(email_template_path)
|
26
|
-
end
|
27
|
-
|
28
|
-
# Notifies users. Finds all users that should be notified
|
29
|
-
# and sends email to each of them. Email is generated
|
30
|
-
# from template.
|
31
|
-
#
|
32
|
-
# @param vms [Array<Berta::VirtualMachineHandler>] Virtual machines
|
33
|
-
# to check for notifications.
|
34
|
-
def notify_users(vms)
|
35
|
-
begin
|
36
|
-
users = service.users
|
37
|
-
rescue Berta::Errors::BackendError => e
|
38
|
-
logger.error e.message
|
39
|
-
return
|
40
|
-
end
|
41
|
-
uids_to_notify(vms).each do |uid, uvms|
|
42
|
-
user = users.find { |usr| usr['ID'] == uid }
|
43
|
-
notify_user(user, uvms) if user
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# Notifies given user about given vms.
|
48
|
-
#
|
49
|
-
# @param user [OpenNebula::User] User to notify
|
50
|
-
# @param user_vms [Array<Berta::VirtualMachineHandler>] VMs to notify about
|
51
|
-
def notify_user(user, user_vms)
|
52
|
-
send_notification(user, user_vms)
|
53
|
-
rescue ArgumentError, Berta::Errors::Entities::NoUserEmailError => e
|
54
|
-
logger.error e.message
|
55
|
-
else
|
56
|
-
user_vms.each(&:update_notified)
|
57
|
-
end
|
58
|
-
|
59
|
-
# Finds and return uids of users from vms that should be notified.
|
60
|
-
#
|
61
|
-
# @param vms [Array<VirtualMachineHandler>] VMs to check for notification
|
62
|
-
# @return [Hash<String, Array<VirtualMachineHandler>>] Hash of user ids to
|
63
|
-
# vms that user with key id should be notified about
|
64
|
-
def uids_to_notify(vms)
|
65
|
-
notif = vms.keep_if(&:should_notify?)
|
66
|
-
uidsvm = Hash.new([])
|
67
|
-
notif.each { |vm| uidsvm[vm.handle['UID']] += [vm] }
|
68
|
-
uidsvm
|
69
|
-
end
|
70
|
-
|
71
|
-
# Sends email to given user about given vms using sendmail. Email
|
72
|
-
# is generated from email template.
|
73
|
-
#
|
74
|
-
# @param user [OpenNebula::User] User to notify
|
75
|
-
# @param vms [Array<Berta::VirtualMachineHandler>] VMs to notify user about
|
76
|
-
# @raise [Berta::Errors::Entities::NoUserEmailError] If user has no email set
|
77
|
-
def send_notification(user, vms)
|
78
|
-
user_email = user['TEMPLATE/EMAIL']
|
79
|
-
user_name = user['NAME']
|
80
|
-
raise Berta::Errors::Entities::NoUserEmailError, "User: #{user_name} with id: #{user['ID']} has no email set" \
|
81
|
-
unless user_email
|
82
|
-
email_text = email_template.render(Hash, user_email: user_email, user_name: user_name, vms: vms_data(vms))
|
83
|
-
logger.debug "Sending mail to user: #{user_name} with email: #{user_email}:\n#{email_text}"
|
84
|
-
return if Berta::Settings['dry-run']
|
85
|
-
mail = Mail.new(email_text)
|
86
|
-
mail.delivery_method :sendmail
|
87
|
-
mail.deliver
|
88
|
-
end
|
89
|
-
|
90
|
-
private
|
91
|
-
|
92
|
-
def vms_data(vms)
|
93
|
-
vms.map do |vm|
|
94
|
-
{ id: vm.handle['ID'],
|
95
|
-
name: vm.handle['NAME'],
|
96
|
-
expiration: vm.default_expiration.time.to_i }
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|