berta 1.4.1 → 1.5.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 +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
|