berta 1.4.1 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +5 -0
- data/config/berta.yml +6 -5
- data/lib/berta/cli.rb +16 -12
- data/lib/berta/command_executor.rb +2 -1
- data/lib/berta/errors/wrong_filter_type_error.rb +5 -0
- data/lib/berta/errors.rb +1 -0
- data/lib/berta/service.rb +17 -12
- data/lib/berta/utils/exclude_filter.rb +15 -0
- data/lib/berta/utils/filter.rb +99 -0
- data/lib/berta/utils/include_filter.rb +15 -0
- data/lib/berta/utils.rb +3 -0
- data/lib/berta/version.rb +1 -1
- data/lib/berta/virtual_machine_handler.rb +4 -0
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1502060c465b5ab799d53bc8491473c8434f9ca1
|
4
|
+
data.tar.gz: db80f4d14ef9cbd0098fada264402b5e7bd84512
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 164b3296d94d8213d9c42556155af66c44d5620ee714536a423b5dc1843e0d63c7b5b5db25b200539f0e222a08a0eb513e45c2bb1ee9fd8ed7e85fc6d0ff220b
|
7
|
+
data.tar.gz: 2d42b4f6a2d2eb2ddabffbc34706977eedaad2c1672b46d9421e1219b72e784e5cc2c4ec6c48de156070377208fb804ab7c4a390d9cb1bf3af55dc1142bf4b9d
|
data/.rubocop.yml
CHANGED
@@ -8,6 +8,8 @@ Metrics/LineLength:
|
|
8
8
|
|
9
9
|
Metrics/MethodLength:
|
10
10
|
Max: 15
|
11
|
+
Exclude:
|
12
|
+
- 'lib/berta/cli.rb'
|
11
13
|
|
12
14
|
Metrics/BlockLength:
|
13
15
|
Exclude:
|
@@ -25,3 +27,6 @@ RSpec/MultipleExpectations:
|
|
25
27
|
|
26
28
|
RSpec/ExampleLength:
|
27
29
|
Enabled: false
|
30
|
+
|
31
|
+
RSpec/NestedGroups:
|
32
|
+
Enabled: false
|
data/config/berta.yml
CHANGED
@@ -7,11 +7,12 @@ berta:
|
|
7
7
|
action: terminate-hard # Type of action that will be executed
|
8
8
|
notification:
|
9
9
|
deadline: 1 day # Time when user should be notified before action will be executed
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
filter: # Filter VMs in after fetch
|
11
|
+
type: exclude # Type of filter, options are include and exclude
|
12
|
+
ids: # VMs with this IDs will be used in filter
|
13
|
+
users: # VMs owned by this users will be used in filter
|
14
|
+
groups: # VMs in this groups will be used in filter
|
15
|
+
clusters: # VMs in this clusters will be used in filter
|
15
16
|
logging:
|
16
17
|
file: /var/log/berta/berta.log # File to write log to. To turn off file logging leave this field empty
|
17
18
|
level: error # Logging level
|
data/lib/berta/cli.rb
CHANGED
@@ -31,17 +31,20 @@ module Berta
|
|
31
31
|
required: true,
|
32
32
|
default: safe_fetch(%w[notification deadline]),
|
33
33
|
type: :string
|
34
|
-
class_option :'
|
35
|
-
default: safe_fetch(%w[
|
34
|
+
class_option :'filter-type',
|
35
|
+
default: safe_fetch(%w[filter type]),
|
36
|
+
type: :string
|
37
|
+
class_option :'filter-ids',
|
38
|
+
default: safe_fetch(%w[filter ids]),
|
36
39
|
type: :array
|
37
|
-
class_option :'
|
38
|
-
default: safe_fetch(%w[
|
40
|
+
class_option :'filter-users',
|
41
|
+
default: safe_fetch(%w[filter users]),
|
39
42
|
type: :array
|
40
|
-
class_option :'
|
41
|
-
default: safe_fetch(%w[
|
43
|
+
class_option :'filter-groups',
|
44
|
+
default: safe_fetch(%w[filter groups]),
|
42
45
|
type: :array
|
43
|
-
class_option :'
|
44
|
-
default: safe_fetch(%w[
|
46
|
+
class_option :'filter-clusters',
|
47
|
+
default: safe_fetch(%w[filter clusters]),
|
45
48
|
type: :array
|
46
49
|
class_option :'dry-run',
|
47
50
|
default: safe_fetch(%w[dry-run]),
|
@@ -80,10 +83,11 @@ module Berta
|
|
80
83
|
settings['expiration']['offset'] = options['expiration-offset']
|
81
84
|
settings['expiration']['action'] = options['expiration-action']
|
82
85
|
settings['notification']['deadline'] = options['notification-deadline']
|
83
|
-
settings['
|
84
|
-
settings['
|
85
|
-
settings['
|
86
|
-
settings['
|
86
|
+
settings['filter']['type'] = options['filter-type']
|
87
|
+
settings['filter']['ids'] = options['filter-ids']
|
88
|
+
settings['filter']['users'] = options['filter-users']
|
89
|
+
settings['filter']['groups'] = options['filter-groups']
|
90
|
+
settings['filter']['clusters'] = options['filter-clusters']
|
87
91
|
settings['dry-run'] = options['dry-run']
|
88
92
|
settings['debug'] = options['debug']
|
89
93
|
settings['logging']['file'] = options['logging-file']
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'erb'
|
2
2
|
require 'tilt'
|
3
|
+
require 'mail'
|
3
4
|
|
4
5
|
module Berta
|
5
6
|
# Class for executing main berta commands
|
@@ -12,6 +13,7 @@ module Berta
|
|
12
13
|
email_template_path = "#{ENV['HOME']}/.berta/#{email_file}" \
|
13
14
|
if File.exist?("#{ENV['HOME']}/.berta/#{email_file}")
|
14
15
|
@email_template = Tilt.new(email_template_path)
|
16
|
+
Mail.defaults { delivery_method :sendmail }
|
15
17
|
end
|
16
18
|
|
17
19
|
# Function that performs clean up operation.
|
@@ -24,7 +26,6 @@ module Berta
|
|
24
26
|
vms = service.running_vms
|
25
27
|
users = service.users
|
26
28
|
vms.each(&:update)
|
27
|
-
Mail.defaults { delivery_method :sendmail }
|
28
29
|
users.each { |user| user.notify(service.user_vms(user), @email_template) }
|
29
30
|
rescue Berta::Errors::BackendError => e
|
30
31
|
logger.error e.message
|
data/lib/berta/errors.rb
CHANGED
@@ -2,6 +2,7 @@ module Berta
|
|
2
2
|
# Module for Berta error classes
|
3
3
|
module Errors
|
4
4
|
autoload :StandardError, 'berta/errors/standard_error'
|
5
|
+
autoload :WrongFilterTypeError, 'berta/errors/wrong_filter_type_error'
|
5
6
|
autoload :BackendError, 'berta/errors/backend_error'
|
6
7
|
autoload :OpenNebula, 'berta/errors/opennebula'
|
7
8
|
autoload :Entities, 'berta/errors/entities'
|
data/lib/berta/service.rb
CHANGED
@@ -6,6 +6,9 @@ module Berta
|
|
6
6
|
attr_reader :endpoint
|
7
7
|
attr_reader :client
|
8
8
|
|
9
|
+
FILTERS = { 'exclude' => Berta::Utils::ExcludeFilter,
|
10
|
+
'include' => Berta::Utils::IncludeFilter }.freeze
|
11
|
+
|
9
12
|
# Initializes service object and connects to opennebula
|
10
13
|
# backend. If both arguments are nil default ONE_AUTH
|
11
14
|
# will be used.
|
@@ -15,6 +18,16 @@ module Berta
|
|
15
18
|
def initialize(secret, endpoint)
|
16
19
|
@endpoint = endpoint
|
17
20
|
@client = OpenNebula::Client.new(secret, endpoint)
|
21
|
+
create_filter
|
22
|
+
end
|
23
|
+
|
24
|
+
def create_filter
|
25
|
+
filter = FILTERS[Berta::Settings.filter.type]
|
26
|
+
raise Berta::Errors::WrongFilterTypeError, "Wrong filter type: #{Berta::Settings.filter.type}" unless filter
|
27
|
+
@filter = filter.new(Berta::Settings.filter.ids,
|
28
|
+
Berta::Settings.filter.users,
|
29
|
+
Berta::Settings.filter.groups,
|
30
|
+
filtered_clusters)
|
18
31
|
end
|
19
32
|
|
20
33
|
# Fetch running vms from OpenNebula and filter out vms that
|
@@ -32,10 +45,7 @@ module Berta
|
|
32
45
|
vm_pool = OpenNebula::VirtualMachinePool.new(client)
|
33
46
|
Berta::Utils::OpenNebula::Helper.handle_error { vm_pool.info_all }
|
34
47
|
logger.debug "Fetched vms: #{vm_pool.map(&:id)}"
|
35
|
-
@cached_vms = Berta::
|
36
|
-
Berta::Settings.exclude.users,
|
37
|
-
Berta::Settings.exclude.groups,
|
38
|
-
excluded_clusters).filter!(vm_pool.map { |vm| Berta::VirtualMachineHandler.new(vm) })
|
48
|
+
@cached_vms = @filter.run(vm_pool.map { |vm| Berta::VirtualMachineHandler.new(vm) })
|
39
49
|
@cached_vms
|
40
50
|
end
|
41
51
|
|
@@ -82,14 +92,9 @@ module Berta
|
|
82
92
|
|
83
93
|
private
|
84
94
|
|
85
|
-
def
|
86
|
-
|
87
|
-
|
88
|
-
clusters.each do |cluster|
|
89
|
-
excluded << cluster if Berta::Settings.exclude.clusters.find { |cname| cname == cluster['NAME'] }
|
90
|
-
end
|
91
|
-
end
|
92
|
-
excluded
|
95
|
+
def filtered_clusters
|
96
|
+
return unless Berta::Settings.filter.clusters
|
97
|
+
clusters.select { |cluster| Berta::Settings.filter.clusters.find { |cname| cname == cluster['NAME'] } }
|
93
98
|
end
|
94
99
|
end
|
95
100
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Berta
|
2
|
+
module Utils
|
3
|
+
# Filter that excludes vms in given params
|
4
|
+
class ExcludeFilter < Filter
|
5
|
+
# Overrides filter method to exclude vms
|
6
|
+
def filter(vmhs)
|
7
|
+
ide = filter_ids(vmhs)
|
8
|
+
usere = filter_users(vmhs)
|
9
|
+
groupe = filter_groups(vmhs)
|
10
|
+
clustere = filter_clusters(vmhs)
|
11
|
+
vmhs - ide - usere - groupe - clustere
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module Berta
|
2
|
+
module Utils
|
3
|
+
# Base Filter class, filters out invalid states
|
4
|
+
class Filter
|
5
|
+
# VM states that take resources
|
6
|
+
RESOURCE_STATES = %w[SUSPENDED POWEROFF CLONING].freeze
|
7
|
+
# Active state has some lcm states that should not expire
|
8
|
+
ACTIVE_STATE = 'ACTIVE'.freeze
|
9
|
+
# LCM states in which active state shouldn't expire
|
10
|
+
NON_RESOURCE_ACTIVE_LCM_STATES = %w[EPILOG SHUTDOWN STOP UNDEPLOY FAILURE].freeze
|
11
|
+
|
12
|
+
# Constructs Filter object.
|
13
|
+
#
|
14
|
+
# @param ids [Array<Numeric>] Ids of VM to filter
|
15
|
+
# @param users [Array<String>] User names to filter
|
16
|
+
# @param groups [Array<String>] Group names to filter
|
17
|
+
# @param clusters [Array<OpenNebula::Cluster>] Clusters to filter
|
18
|
+
def initialize(ids, users, groups, clusters)
|
19
|
+
@ids = ids || []
|
20
|
+
@users = users || []
|
21
|
+
@groups = groups || []
|
22
|
+
@clusters = clusters || []
|
23
|
+
logger.debug "Filter type: #{self.class}"
|
24
|
+
log_filter
|
25
|
+
end
|
26
|
+
|
27
|
+
# Execute this filter
|
28
|
+
#
|
29
|
+
# @param vmhs [Array<Berta::VirtualMachineHandler>] VMs to filter
|
30
|
+
# @return [Array<Berta::VirtualMachineHandler>] Filtered VMs
|
31
|
+
def run(vmhs)
|
32
|
+
fvmhs = vmhs.select { |vmh| takes_resources?(vmh) }
|
33
|
+
logger.debug "Filtered based on RESOURCE: #{(vmhs - fvmhs).map { |vmh| vmh.handle.id }}"
|
34
|
+
fvmhs = filter(fvmhs)
|
35
|
+
logger.debug "VMS after filter : #{fvmhs.map { |vmh| vmh.handle.id }}"
|
36
|
+
fvmhs
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
|
41
|
+
# This method is for child classes to override.
|
42
|
+
# It is executed in `run` method.
|
43
|
+
#
|
44
|
+
# @param vmhs [Array<Berta::VirtualMachineHandler>] VMs without invalid states
|
45
|
+
# @return [Array<Berta::VirtualMachineHandler>] Filtered VMs
|
46
|
+
def filter(vmhs)
|
47
|
+
vmhs
|
48
|
+
end
|
49
|
+
|
50
|
+
# Gets latest cluster id on given VM
|
51
|
+
#
|
52
|
+
# @param vmh [Berta::VirtualMachineHandler] VM to get cluster id on
|
53
|
+
# @return [String] Latest cluster id
|
54
|
+
def latest_cluster_id(vmh)
|
55
|
+
vmh.handle['HISTORY_RECORDS/HISTORY[last()]/CID']
|
56
|
+
end
|
57
|
+
|
58
|
+
def filter_ids(vmhs)
|
59
|
+
idi = vmhs.select { |vmh| @ids.include?(vmh.handle['ID']) }
|
60
|
+
logger.debug "[#{self.class}] filtered based on IDs: #{idi.map { |vmh| vmh.handle.id }}"
|
61
|
+
idi
|
62
|
+
end
|
63
|
+
|
64
|
+
def filter_users(vmhs)
|
65
|
+
useri = vmhs.select { |vmh| @users.include?(vmh.handle['UNAME']) }
|
66
|
+
logger.debug "[#{self.class}] filtered based on USERs: #{useri.map { |vmh| vmh.handle.id }}"
|
67
|
+
useri
|
68
|
+
end
|
69
|
+
|
70
|
+
def filter_groups(vmhs)
|
71
|
+
groupi = vmhs.select { |vmh| @groups.include?(vmh.handle['GNAME']) }
|
72
|
+
logger.debug "[#{self.class}] filtered based on GROUPs: #{groupi.map { |vmh| vmh.handle.id }}"
|
73
|
+
groupi
|
74
|
+
end
|
75
|
+
|
76
|
+
def filter_clusters(vmhs)
|
77
|
+
cids = @clusters.map { |cluster| cluster['ID'] }
|
78
|
+
clusteri = vmhs.select { |vmh| cids.include?(latest_cluster_id(vmh)) }
|
79
|
+
logger.debug "[#{self.class}] filtered based on CLUSTERs: #{clusteri.map { |vmh| vmh.handle.id }}"
|
80
|
+
clusteri
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def takes_resources?(vmh)
|
86
|
+
return true if RESOURCE_STATES.any? { |state| vmh.handle.state_str == state }
|
87
|
+
true if vmh.handle.state_str == ACTIVE_STATE &&
|
88
|
+
NON_RESOURCE_ACTIVE_LCM_STATES.none? { |state| vmh.handle.lcm_state_str.include? state }
|
89
|
+
end
|
90
|
+
|
91
|
+
def log_filter
|
92
|
+
logger.debug "Filter ids : #{@ids}"
|
93
|
+
logger.debug "Filter users : #{@users}"
|
94
|
+
logger.debug "Filter groups : #{@groups}"
|
95
|
+
logger.debug "Filter clusters: #{@clusters.map { |cluster| cluster['NAME'] }}"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Berta
|
2
|
+
module Utils
|
3
|
+
# Filter that includes vms in given params
|
4
|
+
class IncludeFilter < Filter
|
5
|
+
# Overrides filter method to include vms
|
6
|
+
def filter(vmhs)
|
7
|
+
idi = filter_ids(vmhs)
|
8
|
+
useri = filter_users(vmhs)
|
9
|
+
groupi = filter_groups(vmhs)
|
10
|
+
clusteri = filter_clusters(vmhs)
|
11
|
+
idi | useri | groupi | clusteri
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/berta/utils.rb
CHANGED
data/lib/berta/version.rb
CHANGED
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.5.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-05-
|
11
|
+
date: 2017-05-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -271,11 +271,15 @@ 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/errors/wrong_filter_type_error.rb
|
274
275
|
- lib/berta/exclusions.rb
|
275
276
|
- lib/berta/service.rb
|
276
277
|
- lib/berta/settings.rb
|
277
278
|
- lib/berta/user_handler.rb
|
278
279
|
- lib/berta/utils.rb
|
280
|
+
- lib/berta/utils/exclude_filter.rb
|
281
|
+
- lib/berta/utils/filter.rb
|
282
|
+
- lib/berta/utils/include_filter.rb
|
279
283
|
- lib/berta/utils/opennebula.rb
|
280
284
|
- lib/berta/utils/opennebula/helper.rb
|
281
285
|
- lib/berta/version.rb
|
@@ -300,7 +304,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
300
304
|
version: '0'
|
301
305
|
requirements: []
|
302
306
|
rubyforge_project:
|
303
|
-
rubygems_version: 2.6.
|
307
|
+
rubygems_version: 2.6.12
|
304
308
|
signing_key:
|
305
309
|
specification_version: 4
|
306
310
|
summary: Berta VM expiration tool
|