wss_agent 0.0.17 → 0.0.21

Sign up to get free protection for your applications and to get access to all the features.
data/lib/wss_agent.rb CHANGED
@@ -2,7 +2,7 @@ require 'thor'
2
2
  require 'net/http'
3
3
  require 'awesome_print'
4
4
  require 'yaml'
5
- require 'oj'
5
+ require 'multi_json'
6
6
  require 'faraday'
7
7
  require 'faraday_middleware'
8
8
  require 'yell'
@@ -17,9 +17,8 @@ require 'wss_agent/client'
17
17
  require 'wss_agent/gem_sha1'
18
18
  require 'wss_agent/project'
19
19
 
20
-
21
20
  module WssAgent
22
- # Your code goes here...
21
+ DEFAULT_CA_BUNDLE_PATH = File.dirname(__FILE__) + '/data/ca-certificates.crt'
23
22
 
24
23
  class WssAgentError < StandardError
25
24
  def self.status_code(code)
@@ -27,11 +26,11 @@ module WssAgent
27
26
  end
28
27
  end
29
28
 
30
- class NotFoundConfigFile < WssAgentError; status_code(8) ; end
31
- class InvalidConfigFile < WssAgentError; status_code(9) ; end
32
- class TokenNotFound < WssAgentError; status_code(10) ; end
33
- class ApiUrlNotFound < WssAgentError; status_code(11) ; end
34
- class ApiUrlInvalid < WssAgentError; status_code(12) ; end
29
+ class NotFoundConfigFile < WssAgentError; status_code(8); end
30
+ class InvalidConfigFile < WssAgentError; status_code(9); end
31
+ class TokenNotFound < WssAgentError; status_code(10); end
32
+ class ApiUrlNotFound < WssAgentError; status_code(11); end
33
+ class ApiUrlInvalid < WssAgentError; status_code(12); end
35
34
 
36
35
  def self.logger
37
36
  @logger ||= Yell.new STDOUT, level: [:info]
data/lib/wss_agent/cli.rb CHANGED
@@ -1,17 +1,18 @@
1
1
  module WssAgent
2
2
  class CLI < Thor
3
- desc "config", "create config file"
3
+ desc 'config', 'create config file'
4
4
  def config
5
5
  File.open(File.join(Dir.pwd, Configure::CURRENT_CONFIG_FILE), 'w') do |f|
6
6
  f << File.read(Configure.custom_default_path)
7
7
  end
8
8
  ap 'Created the config file: wss_agent.yml'
9
9
  end
10
+ map init: :config
10
11
 
11
12
  desc 'list', 'display list dependencies'
12
- method_options all: :boolean
13
- method_options excludes: :string
14
- method_option :verbose, :aliases => "-v", :desc => "Be verbose"
13
+ method_option :all, type: :boolean
14
+ method_option :excludes, type: :string
15
+ method_option :verbose, aliases: '-v', desc: 'Be verbose'
15
16
  def list
16
17
  WssAgent.enable_debug! if options['verbose']
17
18
  results = Specifications.list(options)
@@ -24,9 +25,10 @@ module WssAgent
24
25
  end
25
26
 
26
27
  desc 'update', 'update open source inventory'
27
- method_options all: :boolean
28
- method_options excludes: :string
29
- method_option :verbose, :aliases => "-v", :desc => "Be verbose"
28
+ method_option :all, type: :boolean
29
+ method_option :excludes, type: :string
30
+ method_option :verbose, aliases: '-v', desc: 'Be verbose'
31
+ method_option :force, type: :boolean, aliases: '-f', desc: 'Force Check All Dependencies'
30
32
  def update
31
33
  WssAgent.enable_debug! if options['verbose']
32
34
  Specifications.update(options)
@@ -35,7 +37,8 @@ module WssAgent
35
37
  end
36
38
 
37
39
  desc 'check_policies', 'checking dependencies that they conforms with company policy.'
38
- method_option :verbose, :aliases => "-v", :desc => "Be verbose"
40
+ method_option :verbose, aliases: '-v', desc: 'Be verbose'
41
+ method_option :force, type: :boolean, aliases: '-f', desc: 'Force Check All Dependencies'
39
42
  def check_policies
40
43
  WssAgent.enable_debug! if options['verbose']
41
44
  Specifications.check_policies(options)
@@ -1,13 +1,16 @@
1
1
  module WssAgent
2
2
  class Client
3
-
4
3
  attr_accessor :connection
5
- CHECK_POLICIES_TYPE = 'CHECK_POLICIES'
6
- UPDATE_TYPE = 'UPDATE'
4
+ POLICY_TYPES = {
5
+ basic: 'CHECK_POLICIES',
6
+ compliance: 'CHECK_POLICY_COMPLIANCE'
7
+ }.freeze
8
+
9
+ UPDATE_TYPE = 'UPDATE'.freeze
7
10
  REQUEST_TIMEOUT = 120
8
11
 
9
12
  def initialize
10
- @connection ||= Faraday.new(Configure.url, { request: { timeout: REQUEST_TIMEOUT } }) do |h|
13
+ @connection ||= Faraday.new(connection_options) do |h|
11
14
  h.port = Configure.port
12
15
  h.headers[:content_type] = 'application/x-www-form-urlencoded'
13
16
  h.request :url_encoded
@@ -25,7 +28,7 @@ module WssAgent
25
28
  if Configure['project_token']
26
29
  diff_data['projectToken'] = Configure['project_token']
27
30
  end
28
- Oj.dump([diff_data])
31
+ MultiJson.dump([diff_data])
29
32
  end
30
33
 
31
34
  def payload(gem_list, options = {})
@@ -41,11 +44,18 @@ module WssAgent
41
44
  end
42
45
 
43
46
  def update(gem_list)
44
- ResponseInventory.new(request(gem_list, { type: UPDATE_TYPE }))
47
+ ResponseInventory.new(request(gem_list, type: UPDATE_TYPE))
45
48
  end
46
49
 
47
- def check_policies(gem_list)
48
- ResponsePolicies.new(request(gem_list, { type: CHECK_POLICIES_TYPE }))
50
+ def check_policies(gem_list, options = {})
51
+ request_options =
52
+ if WssAgent::Configure['force_check_all_dependencies'] || options['force']
53
+ { type: POLICY_TYPES[:compliance], forceCheckAllDependencies: true }
54
+ else
55
+ { type: POLICY_TYPES[:basic], forceCheckAllDependencies: false }
56
+ end
57
+
58
+ ResponsePolicies.new(request(gem_list, request_options))
49
59
  end
50
60
 
51
61
  def request(gem_list, options = {})
@@ -55,5 +65,24 @@ module WssAgent
55
65
  rescue Faraday::Error::ClientError => ex
56
66
  ex
57
67
  end
68
+
69
+ private
70
+
71
+ def connection_options
72
+ @connection_options ||
73
+ begin
74
+
75
+ @connection_options = {
76
+ url: Configure.url,
77
+ request: { timeout: REQUEST_TIMEOUT }
78
+ }
79
+ if Configure.ssl?
80
+ @connection_options[:ssl] = {
81
+ ca_file: WssAgent::DEFAULT_CA_BUNDLE_PATH
82
+ }
83
+ end
84
+ end
85
+ @connection_options
86
+ end
58
87
  end
59
88
  end
@@ -1,16 +1,14 @@
1
1
  module WssAgent
2
2
  class Configure
3
-
4
- DEFAULT_CONFIG_FILE = 'default.yml'
5
- CUSTOM_DEFAULT_CONFIG_FILE = 'custom_default.yml'
6
- CURRENT_CONFIG_FILE = 'wss_agent.yml'
7
- API_PATH = '/agent'
3
+ DEFAULT_CONFIG_FILE = 'default.yml'.freeze
4
+ CUSTOM_DEFAULT_CONFIG_FILE = 'custom_default.yml'.freeze
5
+ CURRENT_CONFIG_FILE = 'wss_agent.yml'.freeze
6
+ API_PATH = '/agent'.freeze
8
7
 
9
8
  extend SingleForwardable
10
9
  def_delegator :current, :[]
11
10
 
12
11
  class << self
13
-
14
12
  def default_path
15
13
  File.join(File.expand_path('../..', __FILE__), 'config', DEFAULT_CONFIG_FILE)
16
14
  end
@@ -38,8 +36,8 @@ module WssAgent
38
36
 
39
37
  @current_config = YAML.load(File.read(current_path))
40
38
 
41
- unless !!@current_config
42
- return raise InvalidConfigFile, "Problem reading wss_agent.yml, please check the file is a valid YAML"
39
+ unless !!@current_config
40
+ return raise InvalidConfigFile, 'Problem reading wss_agent.yml, please check the file is a valid YAML'
43
41
  end
44
42
 
45
43
  default.merge(@current_config)
@@ -53,7 +51,7 @@ module WssAgent
53
51
  URI(@url)
54
52
 
55
53
  rescue URI::Error
56
- raise ApiUrlInvalid, "Api url is invalid. Could you please check url in wss_agent.yml"
54
+ raise ApiUrlInvalid, 'Api url is invalid. Could you please check url in wss_agent.yml'
57
55
  end
58
56
 
59
57
  def port
@@ -65,10 +63,14 @@ module WssAgent
65
63
  [@uri.scheme, @uri.host].join('://')
66
64
  end
67
65
 
66
+ def ssl?
67
+ uri.scheme == 'https'
68
+ end
69
+
68
70
  def api_path
69
71
  @uri = uri
70
72
  @url_path = @uri.path
71
- @url_path == "" ? API_PATH : @url_path
73
+ @url_path == '' ? API_PATH : @url_path
72
74
  end
73
75
 
74
76
  def token
@@ -1,4 +1,4 @@
1
- require "digest"
1
+ require 'digest'
2
2
 
3
3
  module WssAgent
4
4
  class GemSha1
@@ -19,7 +19,7 @@ module WssAgent
19
19
  h.adapter :excon
20
20
  end
21
21
  response = conn.get("/api/v1/versions/#{spec.name}.json")
22
- versions = Oj.load(response.body)
22
+ versions = MultiJson.load(response.body)
23
23
  unless versions.detect { |j| j['number'] == spec.version }
24
24
  spec.version = versions.first['number']
25
25
  end
@@ -61,9 +61,7 @@ module WssAgent
61
61
 
62
62
  when '302' # redirect
63
63
  response = Net::HTTP.get_response(URI(response['location']))
64
- if response.code == '200'
65
- return Digest::SHA1.hexdigest(response.body)
66
- end
64
+ return Digest::SHA1.hexdigest(response.body) if response.code == '200'
67
65
  else # gem isn't found
68
66
  ''
69
67
  end
@@ -71,6 +69,5 @@ module WssAgent
71
69
  rescue Timeout::Error
72
70
  retry_request ? nil : remote_file(true)
73
71
  end
74
-
75
72
  end
76
73
  end
@@ -2,43 +2,39 @@ module WssAgent
2
2
  class Project
3
3
 
4
4
  def project_name
5
- case
6
- when is_gem?
7
- gem.name
8
- when is_rails_app?
9
- rails_app_name
10
- else
11
- folder_name
12
- end
5
+ return gem.name if gem?
6
+ return rails_app_name if rails?
7
+ folder_name
13
8
  end
14
9
 
15
10
  def project_version
16
- if is_gem?
17
- gem.version.to_s
18
- else
19
- ''
20
- end
11
+ gem? ? gem.version.to_s : ''
21
12
  end
22
13
 
23
14
  def folder_name
24
15
  Bundler.root.split.last.to_s
25
16
  end
26
17
 
27
- def is_gem?
18
+ def gem?
28
19
  !Dir.glob(Bundler.root.join('*.gemspec')).last.nil?
29
20
  end
30
21
 
31
22
  def gem
32
- @gem ||= Gem::Specification.load(Dir.glob(Bundler.root.join('*.gemspec')).last)
23
+ @gem ||= Gem::Specification.load(
24
+ Dir.glob(Bundler.root.join('*.gemspec')).last
25
+ )
33
26
  end
34
27
 
35
- def is_rails_app?
36
- !Dir.glob(Bundler.root.join('config', 'application.rb')).last.nil?
28
+ def rails?
29
+ File.exist?(rails_app_path)
37
30
  end
38
31
 
39
32
  def rails_app_name
40
- application_file = File.read(Dir.glob(Bundler.root.join('config', 'application.rb')).last)
41
- application_file.match(/module (\w*)/) && $1
33
+ File.read(rails_app_path).match(/module (\w*)/)[1]
34
+ end
35
+
36
+ def rails_app_path
37
+ Bundler.root.join('config', 'application.rb')
42
38
  end
43
39
  end
44
40
  end
@@ -23,7 +23,7 @@ module WssAgent
23
23
  def parse_response
24
24
  if response.success?
25
25
  begin
26
- @response_data = Oj.load(response.body)
26
+ @response_data = MultiJson.load(response.body)
27
27
  @status = @response_data['status'].to_i
28
28
  @message = @response_data['message']
29
29
  rescue
@@ -49,9 +49,9 @@ module WssAgent
49
49
  end
50
50
 
51
51
  def data
52
- @data ||= Oj.load(response_data['data'])
52
+ @data ||= MultiJson.load(response_data['data'])
53
53
  rescue
54
- response_data && response_data.key?('data') ? response_data['data'] : nil
54
+ response_data && response_data.key?('data') ? response_data['data'] : nil
55
55
  end
56
56
  end
57
57
  end
@@ -6,19 +6,20 @@ module WssAgent
6
6
  @message = "White Source update results: \n"
7
7
  @message << " White Source organization: #{data['organization']} \n"
8
8
 
9
- unless data['createdProjects'].empty?
9
+ if data['createdProjects'].empty?
10
+ @message << " No new projects found \n"
11
+ else
10
12
  @message << " #{data['createdProjects'].size} newly created projects: "
11
13
  @message << data['createdProjects'].join(' ')
12
- else
13
- @message << " No new projects found \n"
14
14
  end
15
15
 
16
- unless data['updatedProjects'].empty?
16
+ if data['updatedProjects'].empty?
17
+ @message << "\n No projects were updated \n"
18
+ else
17
19
  @message << " #{data['updatedProjects'].size} existing projects were updated: "
18
20
  @message << data['updatedProjects'].join(' ')
19
- else
20
- @message << "\n No projects were updated \n"
21
21
  end
22
+
22
23
  @message
23
24
  else
24
25
  super
@@ -1,11 +1,11 @@
1
1
  module WssAgent
2
2
  class ResponsePolicies < Response
3
- REJECT_ACTION = 'Reject'
3
+ REJECT_ACTION = 'Reject'.freeze
4
4
 
5
5
  def parse_response
6
6
  if response.success?
7
7
  begin
8
- @response_data = Oj.load(response.body)
8
+ @response_data = MultiJson.load(response.body)
9
9
  @status = @response_data['status'].to_i
10
10
  @message = @response_data['message']
11
11
  check_new_projects
@@ -20,7 +20,6 @@ module WssAgent
20
20
  end
21
21
  end
22
22
 
23
-
24
23
  def message
25
24
  if success?
26
25
  if policy_violations?
@@ -33,7 +32,7 @@ module WssAgent
33
32
  }.join("\n")
34
33
  @message.join("\n")
35
34
  else
36
- "All dependencies conform with open source policies"
35
+ 'All dependencies conform with open source policies'
37
36
  end
38
37
  end
39
38
  end
@@ -64,8 +63,10 @@ module WssAgent
64
63
  def check(resource)
65
64
  if resource.key?('resource') && resource.key?('policy') &&
66
65
  (resource['policy']['actionType'] == REJECT_ACTION)
67
- add_resource({'resource' => resource['resource'],
68
- 'policy' => resource['policy']})
66
+ add_resource(
67
+ 'resource' => resource['resource'],
68
+ 'policy' => resource['policy']
69
+ )
69
70
  end
70
71
 
71
72
  if resource.key?('children') && resource['children'].is_a?(Array)
@@ -1,4 +1,4 @@
1
- require "digest"
1
+ require 'digest'
2
2
 
3
3
  module WssAgent
4
4
  class Specifications
@@ -10,7 +10,11 @@ module WssAgent
10
10
  # @option options [Boolean] 'all' if true then get all dependencies (include development dependencies)
11
11
  # @option options [String] 'excludes' list gem name which need to exclude from end list
12
12
  def specs(options = {})
13
- list_gems = Bundler::Definition.build(Bundler.default_gemfile, Bundler.default_lockfile, false).specs.to_a
13
+ list_gems = Bundler::Definition.build(
14
+ Bundler.default_gemfile,
15
+ Bundler.default_lockfile,
16
+ false
17
+ ).specs.to_a
14
18
  if options['all']
15
19
  # get all gems
16
20
  list = {}
@@ -31,26 +35,38 @@ module WssAgent
31
35
  new(specs(options)).call
32
36
  end
33
37
 
38
+ def check_policy?(options = {})
39
+ options['force'] ||
40
+ WssAgent::Configure['check_policies'] ||
41
+ WssAgent::Configure['force_check_all_dependencies']
42
+ end
43
+ private :check_policy?
44
+
34
45
  # Send gem list to server
35
46
  #
36
47
  # @param (see Specifications#specs)
37
48
  def update(options = {})
38
49
  wss_client = WssAgent::Client.new
39
- if WssAgent::Configure['check_policies']
40
- policy_results = wss_client.check_policies(WssAgent::Specifications.list(options))
50
+
51
+ if check_policy?(options)
52
+ policy_results = wss_client.check_policies(
53
+ WssAgent::Specifications.list(options),
54
+ options
55
+ )
41
56
  if policy_results.success? && policy_results.policy_violations?
42
57
  puts policy_results.message
43
58
  return false
44
59
  end
45
60
  end
46
61
 
62
+
47
63
  result = wss_client.update(WssAgent::Specifications.list(options))
48
64
  if result.success?
49
65
  WssAgent.logger.debug result.data
50
66
  puts result.message
51
67
  else
52
68
  WssAgent.logger.debug "synchronization errors occur: status: #{result.status}, message: #{result.message}, data: #{result.data}"
53
- ap "error: #{result.status}/#{result.data}", color: {string: :red }
69
+ ap "error: #{result.status}/#{result.data}", color: { string: :red }
54
70
  end
55
71
 
56
72
  result.success?
@@ -61,13 +77,16 @@ module WssAgent
61
77
  # @param (see Specifications#specs)
62
78
  def check_policies(options = {})
63
79
  wss_client = WssAgent::Client.new
64
- result = wss_client.check_policies(WssAgent::Specifications.list(options))
80
+ result = wss_client.check_policies(
81
+ WssAgent::Specifications.list(options),
82
+ options
83
+ )
65
84
  if result.success?
66
85
  WssAgent.logger.debug result.data
67
86
  puts result.message
68
87
  else
69
88
  WssAgent.logger.debug "check policies errors occur: #{result.status}, message: #{result.message}, data: #{result.data}"
70
- ap "error: #{result.status}/#{result.data}", color: {string: :red }
89
+ ap "error: #{result.status}/#{result.data}", color: { string: :red }
71
90
  end
72
91
  end
73
92
 
@@ -84,6 +103,7 @@ module WssAgent
84
103
  if options['excludes'] && options['excludes'].to_s.split(',').include?(gd.name)
85
104
  next
86
105
  end
106
+
87
107
  gs = gd.matching_specs.first
88
108
  if gs
89
109
  unless list[gs.name]
@@ -94,8 +114,10 @@ module WssAgent
94
114
  end
95
115
  else
96
116
  unless list[gd.name]
97
- list[gd.name] = Gem::Specification.new(gd.name,
98
- gd.requirements_list.last.scan(/[\d\.\w]+/).first)
117
+ list[gd.name] = Gem::Specification.new(
118
+ gd.name,
119
+ gd.requirements_list.last.scan(/[\d\.\w]+/).first
120
+ )
99
121
  rm_dep = remote_dependencies(gd.name, gd.requirements_list.last)
100
122
  unless rm_dep.empty?
101
123
  list = gem_dependencies(list, rm_dep, options)
@@ -113,16 +135,20 @@ module WssAgent
113
135
  # @params version [String] version gem
114
136
  #
115
137
  # @return [Array<Gem::Dependency>] list gem dependencies
116
- def remote_dependencies(gem_name, version)
138
+ def remote_dependencies(gem_name, _version)
117
139
  conn = Faraday.new(url: 'https://rubygems.org') do |h|
118
140
  h.headers[:content_type] = 'application/x-www-form-urlencoded'
119
141
  h.request :url_encoded
120
142
  h.adapter :excon
121
143
  end
122
144
  response = conn.get("/api/v1/gems/#{gem_name}.json")
123
- dep_list = Oj.load(response.body)
124
- dep_list['dependencies'].values.flatten.
125
- map { |j| Gem::Dependency.new(j['name'], Gem::Requirement.new(j['requirements'].split(','))) }
145
+ dep_list = MultiJson.load(response.body)
146
+ dep_list['dependencies'].values.flatten.map do |j|
147
+ Gem::Dependency.new(
148
+ j['name'],
149
+ Gem::Requirement.new(j['requirements'].split(','))
150
+ )
151
+ end
126
152
  end
127
153
  end # end class << self
128
154
 
@@ -140,8 +166,8 @@ module WssAgent
140
166
  def gem_item(spec)
141
167
  {
142
168
  'groupId' => spec.name,
143
- 'artifactId' => spec.file_name,
144
- 'version' => spec.version.to_s,
169
+ 'artifactId' => spec.file_name,
170
+ 'version' => spec.version.to_s,
145
171
  'sha1' => GemSha1.new(spec).sha1,
146
172
  'optional' => false,
147
173
  'children' => [],