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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1ce1338b8020499e9cae1605ddf66c0dad404aae
4
- data.tar.gz: dea58173ca736a372e9b6a30f3b08a29efa282b7
3
+ metadata.gz: 1502060c465b5ab799d53bc8491473c8434f9ca1
4
+ data.tar.gz: db80f4d14ef9cbd0098fada264402b5e7bd84512
5
5
  SHA512:
6
- metadata.gz: db63fd0e325e176bd390db3481f48b063077d21e5b0edd6db0d00498cd48a9b0b65a46fc4b205da9e59a2c189994fe39450809be103e4bd60247d4be0fc1fba5
7
- data.tar.gz: 6e12df6f7cec8f294ed0893528208a317ac40695e51d12d765fdf7e70961234ab081e9449e08c8da4bade3f2314e86c2bb642dd81dc44ddb8e05711f94daf326
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
- exclude: # Exclude VMs to ignore them
11
- ids: # VMs with this IDs will be ignored
12
- users: # VMs owned by this users will be ignored
13
- groups: # VMs in this groups will be ignored
14
- clusters: # VMs in this clusters will be ignored
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 :'exclude-ids',
35
- default: safe_fetch(%w[exclude ids]),
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 :'exclude-users',
38
- default: safe_fetch(%w[exclude users]),
40
+ class_option :'filter-users',
41
+ default: safe_fetch(%w[filter users]),
39
42
  type: :array
40
- class_option :'exclude-groups',
41
- default: safe_fetch(%w[exclude groups]),
43
+ class_option :'filter-groups',
44
+ default: safe_fetch(%w[filter groups]),
42
45
  type: :array
43
- class_option :'exclude-clusters',
44
- default: safe_fetch(%w[exclude clusters]),
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['exclude']['ids'] = options['exclude-ids']
84
- settings['exclude']['users'] = options['exclude-users']
85
- settings['exclude']['groups'] = options['exclude-groups']
86
- settings['exclude']['clusters'] = options['exclude-clusters']
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
@@ -0,0 +1,5 @@
1
+ module Berta
2
+ module Errors
3
+ class WrongFilterTypeError < StandardError; end
4
+ end
5
+ end
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::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) })
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 excluded_clusters
86
- excluded = []
87
- if Berta::Settings.exclude.clusters
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
@@ -2,5 +2,8 @@ module Berta
2
2
  # Utility classes
3
3
  module Utils
4
4
  autoload :OpenNebula, 'berta/utils/opennebula'
5
+ autoload :Filter, 'berta/utils/filter'
6
+ autoload :ExcludeFilter, 'berta/utils/exclude_filter'
7
+ autoload :IncludeFilter, 'berta/utils/include_filter'
5
8
  end
6
9
  end
data/lib/berta/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Berta
2
- VERSION = '1.4.1'.freeze
2
+ VERSION = '1.5.0'.freeze
3
3
  end
@@ -93,6 +93,10 @@ module Berta
93
93
  time.to_i if time
94
94
  end
95
95
 
96
+ def ==(other)
97
+ handle.id == other.handle.id
98
+ end
99
+
96
100
  private
97
101
 
98
102
  # Sets array of expirations to vm, rewrites all old ones.
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.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-04 00:00:00.000000000 Z
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.11
307
+ rubygems_version: 2.6.12
304
308
  signing_key:
305
309
  specification_version: 4
306
310
  summary: Berta VM expiration tool