berta 1.4.0 → 1.4.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|