outliers 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/README.md +6 -66
  4. data/lib/outliers/cli/process.rb +12 -3
  5. data/lib/outliers/cli.rb +0 -24
  6. data/lib/outliers/collection.rb +15 -15
  7. data/lib/outliers/filters/aws/ec2/tags.rb +1 -1
  8. data/lib/outliers/info.rb +12 -0
  9. data/lib/outliers/provider.rb +0 -4
  10. data/lib/outliers/providers/aws/cloud_formation.rb +1 -5
  11. data/lib/outliers/providers/aws/ec2.rb +1 -5
  12. data/lib/outliers/providers/aws/elb.rb +1 -5
  13. data/lib/outliers/providers/aws/iam.rb +1 -5
  14. data/lib/outliers/providers/aws/rds.rb +1 -5
  15. data/lib/outliers/providers/aws/s3.rb +1 -5
  16. data/lib/outliers/providers/aws/{base.rb → shared.rb} +0 -10
  17. data/lib/outliers/providers/aws/sqs.rb +1 -5
  18. data/lib/outliers/providers/aws.rb +1 -1
  19. data/lib/outliers/resources/aws/ec2/instance.rb +0 -16
  20. data/lib/outliers/resources/aws/ec2/security_group.rb +0 -7
  21. data/lib/outliers/resources/aws/elb/load_balancer.rb +0 -7
  22. data/lib/outliers/resources/aws/iam/user.rb +0 -10
  23. data/lib/outliers/resources/aws/rds/db_instance.rb +0 -10
  24. data/lib/outliers/resources/aws/s3/bucket.rb +0 -13
  25. data/lib/outliers/resources.rb +4 -0
  26. data/lib/outliers/run.rb +24 -8
  27. data/lib/outliers/verifications/shared.rb +4 -16
  28. data/lib/outliers/version.rb +1 -1
  29. data/lib/outliers.rb +1 -0
  30. data/reference.yaml +128 -0
  31. data/spec/collection_spec.rb +3 -3
  32. data/spec/filters/aws/ec2/tags_spec.rb +1 -1
  33. data/spec/info_spec.rb +41 -0
  34. data/spec/run_spec.rb +57 -10
  35. data/spec/verifications/shared_spec.rb +6 -6
  36. metadata +7 -6
  37. data/lib/outliers/cli/evaluate.rb +0 -136
  38. data/lib/outliers/cli/providers.rb +0 -29
  39. data/lib/outliers/cli/resources.rb +0 -60
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ca2a95007c8c6b9d85847b7c857e8e5f54e72859
4
- data.tar.gz: 273c267dc763814b17162cf394cc453e77ba2253
3
+ metadata.gz: 74e9cb409e6eef3f41b71f7546b03a331acd8e78
4
+ data.tar.gz: 3bf117be6746ca6f358e53b063c8c46226ad8d23
5
5
  SHA512:
6
- metadata.gz: efbb5c48979eafc1001695502ad892ae799517497b789e6b56d034b44e0e3cdf74fa40c950cf77e9fd329cd0afbe1fb4ab612497c6b0a33ab7d00e95c1b75cba
7
- data.tar.gz: a2a0da57894add6de86c37a749d172a8174476b12f1d8665ebe68df9b11c31271bab95de1c1171f401cc4f8a2619e9726ad426f62b66914ec0e1b280f8aa74e4
6
+ metadata.gz: 64869c01820ae1d1e323c9531bafd25c10d57ef2660b4b6f505967a81256b974e05d4f9e9732bbb31dc785c7116227651a65fa2100e2330b8715e2452562d4c9
7
+ data.tar.gz: c9e49150e28457a4152b9cb5572ab9851e34c3fcf9742782d50a12afbc0043cacbb2b740addcc740256991486a4efeca4bb5ec721ae828c445d952665b5e00e6
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## HEAD
2
+
3
+ ## 0.3.0
4
+
5
+ * Remove CLI support
6
+ * Pull resource and provider info from reference.yaml
7
+ * Support running multiple evaluation threads
8
+
1
9
  ## 0.2.0
2
10
 
3
11
  * Added filters
data/README.md CHANGED
@@ -9,8 +9,8 @@ Outliers is a framework for verifying configuration of resources.
9
9
  * Applications and teams rely on multiple service providers (AWS, etc).
10
10
  * Providers deliver like resources with complex configuration (EC2 Instances, S3 Buckets, etc).
11
11
  * Resource configuration can be verified (launched from given AMI, contain private objects, etc).
12
- * The resources can be included or excluded by their ID (Instance ID, Object Key, etc).
13
- * Resources can be included in the list by matching a filter (Instance has tag 'x' with value 'y').
12
+ * Resources can be targeted or excluded by their ID (Instance ID, Object Key, etc).
13
+ * Resources can be targeted or excluded by matching a filter (Instance has tag 'x' with value 'y').
14
14
  * Those not passing verifications, are flagged as Outliers.
15
15
 
16
16
  ## Requirements
@@ -47,53 +47,9 @@ Multiple accounts can be specified, to add a prod and preprod AWS account:
47
47
 
48
48
  Depending on the provider, different keys and values are required.
49
49
 
50
- For a list of providers:
51
-
52
- outliers providers
53
-
54
50
  ## Usage
55
51
 
56
- Outliers can be used in two modes, as a **CLI** or a **DSL**.
57
-
58
- The CLI is good for testing and quick verifications.
59
-
60
- The DSL can be used to build up comprehensive list of verifications for a project or company.
61
-
62
- ### CLI
63
-
64
- To verify all EC2 instances are in a VPC:
65
-
66
- outliers evaluate -c aws_prod -p aws_ec2 -r instance -v vpc
67
-
68
- Credential keys can be overriden. To specify region us-west-1.
69
-
70
- outliers evaluate -c aws_prod -p aws_ec2 -r instance -v vpc -c region=us-west-1
71
-
72
- Verifications may require arguments. To verify your RDS databases have a 2 day retention period:
73
-
74
- outliers evaluate -c aws_prod -p aws_rds -r db_instance -v backup_retention_period -a days=2
75
-
76
- Verifications may accept multiple values for an argument. Values are separated by commas.
77
-
78
- To verify EC2 instances are launched from a list of known images:
79
-
80
- outliers evaluate -c aws_prod -p aws_ec2 -r instance -v valid_image_id -a image_ids=ami-12345678,ami-87654321
81
-
82
- To only target a specific resource:
83
-
84
- outliers evaluate -c aws_prod -p aws_ec2 -r instance -t i-87654321
85
-
86
- To exclude resources that are known exceptions:
87
-
88
- outliers evaluate -c aws_prod -p aws_ec2 -r instance -e i-12345678
89
-
90
- Resources have attributes which can be used to filter target resources. To filter instances who have tag 'Name' equal to 'web'.
91
-
92
- outliers evaluate -c aws_prod -p aws_ec2 -r instance -f 'tag=Name:web'
93
-
94
- ### DSL
95
-
96
- To run Outliers as a DSL
52
+ Outlier's DSL can be used to build up comprehensive list of verifications for a project or application.
97
53
 
98
54
  * Create a directory to store your evaluations.
99
55
  * Evalutions are read from from files within the directory.
@@ -195,7 +151,9 @@ Sometimes you want to exclude resources that are known exceptions, to exclude an
195
151
  verify 'valid_image_id', image_ids: ['ami-12345678','ami-87654321']
196
152
  end
197
153
 
198
- Resources have attributes which can be used to filter target resources. To filter instances who have tag 'Name' equal to 'web'.
154
+ Resources have attributes which can be used to filter target resources.
155
+
156
+ To filter instances who have tag 'Name' equal to 'web'.
199
157
 
200
158
  evaluate do
201
159
  connect 'aws_prod', provider: 'aws_ec2', region: 'us-west-1'
@@ -204,24 +162,6 @@ Resources have attributes which can be used to filter target resources. To filte
204
162
  verify 'valid_image_id', image_ids: ['ami-12345678','ami-87654321']
205
163
  end
206
164
 
207
- ### Help
208
-
209
- For a list of providers and required credentials:
210
-
211
- outliers providers
212
-
213
- For a list of resources, and available verifications, for a given provider:
214
-
215
- outliers resources -p PROVIDER_NAME
216
-
217
- For a fule list of commands run:
218
-
219
- outliers -h
220
-
221
- For full help on a command, append -h:
222
-
223
- outliers evaluate -h
224
-
225
165
  ## Contributing
226
166
 
227
167
  1. Fork it
@@ -2,7 +2,7 @@ module Outliers
2
2
  module CLI
3
3
  class Process
4
4
  def process
5
- @options = {}
5
+ @options = { threads: 1 }
6
6
 
7
7
  option_parser.parse!
8
8
 
@@ -11,9 +11,14 @@ module Outliers
11
11
  @logger = Outliers.logger
12
12
  @run = Run.new
13
13
 
14
+ if @options[:threads] > 1
15
+ @run.threaded = true
16
+ @run.thread_count = @options[:threads]
17
+ end
18
+
14
19
  begin
15
20
  @run.credentials = Credentials.load_from_file "#{ENV['HOME']}/.outliers.yml"
16
- @run.process_evaluations_in_config_folder
21
+ @run.process_evaluations_in_dir
17
22
  rescue Outliers::Exceptions::Base => e
18
23
  @logger.error e.message
19
24
  exit 1
@@ -26,7 +31,7 @@ module Outliers
26
31
 
27
32
  @run.failed.each do |f|
28
33
  @logger.info "Evaluation '#{f.evaluation}' verification '#{f.verification}' of '#{f.resource}' failed."
29
- @logger.debug "Failing resource IDs '#{f.failing_resources.map{|r| r.id}.join(', ')}'"
34
+ @logger.info "Failing resource IDs '#{f.failing_resources.map{|r| r.id}.join(', ')}'"
30
35
  end
31
36
 
32
37
  @logger.info "(#{failed} evaluations failed, #{passed} evaluations passed.)"
@@ -48,6 +53,10 @@ module Outliers
48
53
  OptionParser.new do |opts|
49
54
  opts.banner = "Usage: outliers process [options]"
50
55
 
56
+ opts.on("-t", "--threads [THREADS]", "Maximum number of evaluations threads to run concurrently (Default: 1).") do |o|
57
+ @options[:threads] = o.to_i
58
+ end
59
+
51
60
  opts.on("-d", "--directory [DIRECTORY]", "Directory containing evaluations to load.") do |o|
52
61
  @options[:directory] = o
53
62
  end
data/lib/outliers/cli.rb CHANGED
@@ -1,9 +1,6 @@
1
1
  require 'optparse'
2
2
 
3
- require 'outliers/cli/evaluate'
4
3
  require 'outliers/cli/process'
5
- require 'outliers/cli/providers'
6
- require 'outliers/cli/resources'
7
4
 
8
5
  module Outliers
9
6
  module CLI
@@ -12,20 +9,6 @@ module Outliers
12
9
  cmd = ARGV.shift
13
10
 
14
11
  case cmd
15
- when 'evaluate'
16
- begin
17
- CLI::Evaluate.new.evaluate
18
- rescue OptionParser::MissingArgument => e
19
- puts e.message
20
- exit 1
21
- end
22
- when 'providers'
23
- begin
24
- CLI::Providers.new.providers
25
- rescue OptionParser::MissingArgument => e
26
- puts e.message
27
- exit 1
28
- end
29
12
  when 'process'
30
13
  begin
31
14
  CLI::Process.new.process
@@ -33,13 +16,6 @@ module Outliers
33
16
  puts e.message
34
17
  exit 1
35
18
  end
36
- when 'resources'
37
- begin
38
- CLI::Resources.new.resources
39
- rescue OptionParser::MissingArgument => e
40
- puts e.message
41
- exit 1
42
- end
43
19
  when '-v'
44
20
  puts OUTLIERS::VERSION
45
21
  else
@@ -37,15 +37,15 @@ module Outliers
37
37
  end
38
38
 
39
39
  def each &block
40
- all.each do |resource|
40
+ list.each do |resource|
41
41
  block.call resource
42
42
  end
43
43
  end
44
44
 
45
45
  def exclude_by_key(exclusions)
46
46
  @logger.info "Excluding the following resources: '#{exclusions.join(',')}'."
47
- save = all.reject {|u| exclusions.include? u.public_send key}
48
- @all = save
47
+ save = list.reject {|u| exclusions.include? u.public_send key}
48
+ @list = save
49
49
  end
50
50
 
51
51
  def filter(args)
@@ -62,18 +62,18 @@ module Outliers
62
62
 
63
63
  logger.warn "No resources match filter." unless filtered_list.any?
64
64
 
65
- @all = filtered_list
65
+ @list = filtered_list
66
66
  end
67
67
 
68
68
  def verify(name, arguments={})
69
69
  name << "?" unless name =~ /^.*\?$/
70
70
 
71
- unless all.any?
71
+ unless list.any?
72
72
  return { failing_resources: [], passing_resources: [] }
73
73
  end
74
74
 
75
75
  logger.info "Verifying '#{name}'."
76
- logger.debug "Target resources '#{all_by_key.join(', ')}'."
76
+ logger.debug "Target resources '#{list_by_key.join(', ')}'."
77
77
 
78
78
  unless verification_exists? name
79
79
  raise Exceptions::UnknownVerification.new "Unkown verification '#{name}'."
@@ -86,8 +86,8 @@ module Outliers
86
86
  end
87
87
  end
88
88
 
89
- def all
90
- @all ||= load_all
89
+ def list
90
+ @list ||= load_all
91
91
  end
92
92
 
93
93
  def key
@@ -107,8 +107,8 @@ module Outliers
107
107
  m.include? name.to_sym
108
108
  end
109
109
 
110
- def all_by_key
111
- all.map {|r| r.public_send key}
110
+ def list_by_key
111
+ list.map {|r| r.public_send key}
112
112
  end
113
113
 
114
114
  def connect
@@ -126,13 +126,13 @@ module Outliers
126
126
  def set_target_resources(verification)
127
127
  logger.info "Verifying target '#{targets.join(', ')}'."
128
128
 
129
- @all = all.select {|r| targets.include? r.id }
129
+ @list = list.select {|r| targets.include? r.id }
130
130
 
131
- unless all.any?
131
+ unless list.any?
132
132
  raise Outliers::Exceptions::TargetNotFound.new "No resources found matching one or more of '#{targets}'."
133
133
  end
134
134
 
135
- @all
135
+ @list
136
136
  end
137
137
 
138
138
  def send_resources_verification(verification, arguments)
@@ -143,12 +143,12 @@ module Outliers
143
143
  logger.debug "Verification of resource '#{resource.id}' #{result ? 'passed' : 'failed'}."
144
144
  result
145
145
  end
146
- { failing_resources: failing_resources, passing_resources: all - failing_resources }
146
+ { failing_resources: failing_resources, passing_resources: list - failing_resources }
147
147
  end
148
148
 
149
149
  def send_collection_verification(verification, arguments)
150
150
  failing_resources = send_verification(self, verification, arguments)
151
- { failing_resources: failing_resources, passing_resources: all - failing_resources }
151
+ { failing_resources: failing_resources, passing_resources: list - failing_resources }
152
152
  end
153
153
 
154
154
  def send_verification(object, verification, arguments)
@@ -8,7 +8,7 @@ module Outliers
8
8
  tag_name = value.split(':').first
9
9
  tag_value = value.split(':').last
10
10
  logger.info "Filtering by tag '#{tag_name}' equals '#{tag_value}'."
11
- all.select do |r|
11
+ list.select do |r|
12
12
  if r.tags.has_key? tag_name
13
13
  value = r.tags[tag_name]
14
14
  result = value == tag_value
@@ -0,0 +1,12 @@
1
+ require 'yaml'
2
+
3
+ module Outliers
4
+ module Info
5
+ module_function
6
+
7
+ def reference
8
+ YAML.load_file(File.expand_path(File.join(File.dirname(__FILE__), '../../reference.yaml')))
9
+ end
10
+
11
+ end
12
+ end
@@ -14,10 +14,6 @@ module Outliers
14
14
  (self.to_s.split('::') - ['Outliers', 'Providers']).map { |p| p.underscore }.join('_').downcase
15
15
  end
16
16
 
17
- def self.credential_arguments
18
- {}
19
- end
20
-
21
17
  def initialize(credentials)
22
18
  @credentials = credentials
23
19
  @logger = Outliers.logger
@@ -5,12 +5,8 @@ module Outliers
5
5
 
6
6
  include Shared
7
7
 
8
- def self.credential_arguments
9
- Shared.credential_arguments
10
- end
11
-
12
8
  def connect
13
- logger.info "Connecting to region '#{@region}'." unless @cf
9
+ logger.debug "Connecting to region '#{@region}'." unless @cf
14
10
  @cf ||= ::AWS::CloudFormation.new config
15
11
  end
16
12
 
@@ -5,12 +5,8 @@ module Outliers
5
5
 
6
6
  include Shared
7
7
 
8
- def self.credential_arguments
9
- Shared.credential_arguments
10
- end
11
-
12
8
  def connect
13
- logger.info "Connecting to region '#{@region}'." unless @ec2
9
+ logger.debug "Connecting to region '#{@region}'." unless @ec2
14
10
  @ec2 ||= ::AWS::EC2.new config
15
11
  end
16
12
 
@@ -5,12 +5,8 @@ module Outliers
5
5
 
6
6
  include Shared
7
7
 
8
- def self.credential_arguments
9
- Shared.credential_arguments
10
- end
11
-
12
8
  def connect
13
- logger.info "Connecting to region '#{@region}'." unless @elb
9
+ logger.debug "Connecting to region '#{@region}'." unless @elb
14
10
  @elb ||= ::AWS::ELB.new config
15
11
  end
16
12
 
@@ -5,12 +5,8 @@ module Outliers
5
5
 
6
6
  include Shared
7
7
 
8
- def self.credential_arguments
9
- Shared.credential_arguments
10
- end
11
-
12
8
  def connect
13
- logger.info "Connecting to region '#{@region}'." unless @iam
9
+ logger.debug "Connecting to region '#{@region}'." unless @iam
14
10
  @iam ||= ::AWS::IAM.new config
15
11
  end
16
12
 
@@ -5,12 +5,8 @@ module Outliers
5
5
 
6
6
  include Shared
7
7
 
8
- def self.credential_arguments
9
- Shared.credential_arguments
10
- end
11
-
12
8
  def connect
13
- logger.info "Connecting to region '#{@region}'." unless @rds
9
+ logger.debug "Connecting to region '#{@region}'." unless @rds
14
10
  @rds ||= ::AWS::RDS.new config
15
11
  end
16
12
 
@@ -5,12 +5,8 @@ module Outliers
5
5
 
6
6
  include Shared
7
7
 
8
- def self.credential_arguments
9
- Shared.credential_arguments
10
- end
11
-
12
8
  def connect
13
- logger.info "Connecting to region '#{@region}'." unless @iam
9
+ logger.debug "Connecting to region '#{@region}'." unless @iam
14
10
  @iam ||= ::AWS::S3.new config
15
11
  end
16
12
 
@@ -17,16 +17,6 @@ module Outliers
17
17
  :region => @region }
18
18
  end
19
19
 
20
- module_function
21
-
22
- def credential_arguments
23
- {
24
- 'access_key_id' => 'AWS Account Access Key',
25
- 'secret_access_key' => 'AWS Account Secret Key',
26
- 'region' => 'AWS Region (Default us-east-1)'
27
- }
28
- end
29
-
30
20
  end
31
21
  end
32
22
  end
@@ -5,12 +5,8 @@ module Outliers
5
5
 
6
6
  include Shared
7
7
 
8
- def self.credential_arguments
9
- Shared.credential_arguments
10
- end
11
-
12
8
  def connect
13
- logger.info "Connecting to region '#{@region}'." unless @sqs
9
+ logger.debug "Connecting to region '#{@region}'." unless @sqs
14
10
  @sqs ||= ::AWS::SQS.new config
15
11
  end
16
12
 
@@ -1,4 +1,4 @@
1
- require 'outliers/providers/aws/base'
1
+ require 'outliers/providers/aws/shared'
2
2
 
3
3
  require 'outliers/providers/aws/cloud_formation'
4
4
  require 'outliers/providers/aws/ec2'
@@ -7,22 +7,6 @@ module Outliers
7
7
  'instance_id'
8
8
  end
9
9
 
10
- def self.verifications
11
- [
12
- { name: 'classic',
13
- description: 'Instance is in AWS Classic (No VPC).' },
14
- { name: 'source_dest_check',
15
- description: 'Instance source dest check set to true.' },
16
- { name: 'running',
17
- description: 'Instance status is running.' },
18
- { name: 'valid_image_id',
19
- description: 'ami_ids=ami_id1,ami_id2 - Instances Image ID (AMI) is in given list.',
20
- args: 'image_ids: [IMAGE_ID1, IMAGEID2]' },
21
- { name: 'vpc',
22
- description: 'Instance is in a VPC.' }
23
- ]
24
- end
25
-
26
10
  def classic?
27
11
  !vpc?
28
12
  end
@@ -3,13 +3,6 @@ module Outliers
3
3
  module Aws
4
4
  module Ec2
5
5
  class SecurityGroup < Resource
6
- def self.verifications
7
- [
8
- { name: 'no_public_internet_ingress',
9
- description: 'Security Group has no rules open to "0.0.0.0/0".' }
10
- ]
11
- end
12
-
13
6
  def no_public_internet_ingress?
14
7
  logger.debug "Verifying '#{id}'."
15
8
  source.ip_permissions.select do |i|
@@ -3,13 +3,6 @@ module Outliers
3
3
  module Aws
4
4
  module Elb
5
5
  class LoadBalancer < Resource
6
- def self.verifications
7
- [
8
- { name: 'ssl_certificates_valid',
9
- description: 'Validates all SSL certificates associated with an ELB are valid for given number of days',
10
- args: 'days: DAYS' }
11
- ]
12
- end
13
6
 
14
7
  def ssl_certificates_valid?(args)
15
8
  days = args[:days]
@@ -3,16 +3,6 @@ module Outliers
3
3
  module Aws
4
4
  module Iam
5
5
  class User < Resource
6
- def self.verifications
7
- [
8
- { name: 'mfa_enabled',
9
- description: 'Verify MFA enabled for user.' },
10
- { name: 'no_access_keys',
11
- description: 'Verify user has no access keys.' },
12
- { name: 'no_password_set',
13
- description: 'Verify password not set for user.' }
14
- ]
15
- end
16
6
 
17
7
  def no_access_keys?
18
8
  logger.debug "#{id} has #{access_keys.count} access key(s)."
@@ -7,16 +7,6 @@ module Outliers
7
7
  'db_instance_identifier'
8
8
  end
9
9
 
10
- def self.verifications
11
- [
12
- { name: 'backup_retention_period',
13
- description: 'Validate the backup retention period equals given days for the db_instance.',
14
- args: 'days: DAYS' },
15
- { name: 'multi_az',
16
- description: 'RDS Multi AZ set to yes.' }
17
- ]
18
- end
19
-
20
10
  def backup_retention_period?(args)
21
11
  days = args[:days]
22
12
 
@@ -4,19 +4,6 @@ module Outliers
4
4
  module S3
5
5
  class Bucket < Resource
6
6
 
7
- def self.verifications
8
- [
9
- { name: 'empty',
10
- description: 'Bucket has no objects.' },
11
- { name: 'no_public_objects',
12
- description: 'Bucket has no public accessible objects.' },
13
- { name: 'configured_as_website',
14
- description: 'Bucket is configured as a website.' },
15
- { name: 'not_configured_as_website',
16
- description: 'Bucket is not configured as a website.' }
17
- ]
18
- end
19
-
20
7
  def empty?
21
8
  logger.debug "Bucket #{id} has #{count} objects."
22
9
 
@@ -4,6 +4,10 @@ module Outliers
4
4
  module Resources
5
5
  module_function
6
6
 
7
+ def list
8
+ Outliers::Resources.collections
9
+ end
10
+
7
11
  def collections
8
12
  all_the_modules.select {|m| (m.is_a? Class) && (m.to_s =~ /Collection$/)}
9
13
  end
data/lib/outliers/run.rb CHANGED
@@ -1,24 +1,35 @@
1
1
  module Outliers
2
2
  class Run
3
- attr_accessor :credentials, :results
4
-
5
- def initialize
6
- @results = []
3
+ attr_accessor :credentials, :results, :threads, :threaded, :thread_count
4
+
5
+ def initialize(options={})
6
+ @results = []
7
+ @threads = []
8
+ @threaded = false
9
+ @thread_count = 1
10
+ Thread.abort_on_exception = true
7
11
  end
8
12
 
9
- def process_evaluations_in_config_folder
10
- evaluations_path = File.join Outliers.config_path
11
- files = Dir.glob(File.join(evaluations_path, '**', '*'))
13
+ def process_evaluations_in_dir
12
14
  files.each do |file|
13
15
  next if File.directory? file
14
16
  next if File.extname(file) != '.rb'
15
17
  logger.info "Processing '#{file}'."
16
18
  self.instance_eval File.read(file)
17
19
  end
20
+
21
+ threads.each {|t| t.join}
18
22
  end
19
23
 
20
24
  def evaluate(name='unspecified', &block)
21
- Evaluation.new(:name => name, :run => self).instance_eval &block
25
+ while Thread.list.count > thread_count
26
+ logger.info "Maximum concurrent threads running, sleeping."
27
+ sleep 2
28
+ end
29
+
30
+ evaluation = Proc.new { Evaluation.new(:name => name, :run => self).instance_eval &block }
31
+
32
+ threaded ? threads << Thread.new { evaluation.call } : evaluation.call
22
33
  end
23
34
 
24
35
  def passed
@@ -31,6 +42,11 @@ module Outliers
31
42
 
32
43
  private
33
44
 
45
+ def files
46
+ evaluations_path = File.join Outliers.config_path
47
+ files = Dir.glob File.join(evaluations_path, '**', '*')
48
+ end
49
+
34
50
  def logger
35
51
  @logger ||= Outliers.logger
36
52
  end