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 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