Class: JiraGateway

Inherits:
Object
  • Object
show all
Defined in:
lib/jirametrics/jira_gateway.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file_system:, jira_config:, settings:) ⇒ JiraGateway

Returns a new instance of JiraGateway.



12
13
14
15
16
17
# File 'lib/jirametrics/jira_gateway.rb', line 12

def initialize file_system:, jira_config:, settings:
  @file_system = file_system
  load_jira_config(jira_config)
  @settings = settings
  @ignore_ssl_errors = settings['ignore_ssl_errors']
end

Instance Attribute Details

#file_systemObject (readonly)

Returns the value of attribute file_system.



10
11
12
# File 'lib/jirametrics/jira_gateway.rb', line 10

def file_system
  @file_system
end

#ignore_ssl_errorsObject

Returns the value of attribute ignore_ssl_errors.



9
10
11
# File 'lib/jirametrics/jira_gateway.rb', line 9

def ignore_ssl_errors
  @ignore_ssl_errors
end

#jira_urlObject (readonly)

Returns the value of attribute jira_url.



10
11
12
# File 'lib/jirametrics/jira_gateway.rb', line 10

def jira_url
  @jira_url
end

#settingsObject (readonly)

Returns the value of attribute settings.



10
11
12
# File 'lib/jirametrics/jira_gateway.rb', line 10

def settings
  @settings
end

Instance Method Details

#call_url(relative_url:) ⇒ Object



49
50
51
52
# File 'lib/jirametrics/jira_gateway.rb', line 49

def call_url relative_url:
  command = make_curl_command url: "#{@jira_url}#{relative_url}"
  exec_and_parse_response command: command, stdin_data: nil
end

#capture3(command, stdin_data:) ⇒ Object



44
45
46
47
# File 'lib/jirametrics/jira_gateway.rb', line 44

def capture3 command, stdin_data:
  # In it's own method so we can mock it out in tests
  Open3.capture3(command, stdin_data: stdin_data)
end

#cloud?Boolean

Returns:

  • (Boolean)


119
120
121
# File 'lib/jirametrics/jira_gateway.rb', line 119

def cloud?
  @jira_url.downcase.end_with? '.atlassian.net'
end

#exec_and_parse_response(command:, stdin_data:) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/jirametrics/jira_gateway.rb', line 24

def exec_and_parse_response command:, stdin_data:
  log_entry = "  #{command.gsub(/\s+/, ' ')}"
  log_entry = sanitize_message log_entry
  @file_system.log log_entry

  stdout, stderr, status = capture3(command, stdin_data: stdin_data)
  unless status.success?
    @file_system.log "Failed call with exit status #{status.exitstatus}!"
    @file_system.log "Returned (stdout): #{stdout.inspect}"
    @file_system.log "Returned (stderr): #{stderr.inspect}"
    raise "Failed call with exit status #{status.exitstatus}. " \
      "See #{@file_system.logfile_name} for details"
  end

  @file_system.log "Returned (stderr): #{stderr.inspect}" unless stderr == ''
  raise 'no response from curl on stdout' if stdout == ''

  parse_response(command: command, result: stdout)
end

#json_successful?(json) ⇒ Boolean

Returns:

  • (Boolean)


112
113
114
115
116
117
# File 'lib/jirametrics/jira_gateway.rb', line 112

def json_successful? json
  return false if json.is_a?(Hash) && (json['error'] || json['errorMessages'] || json['errorMessage'])
  return false if json.is_a?(Array) && json.first == 'errorMessage'

  true
end

#load_jira_config(jira_config) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/jirametrics/jira_gateway.rb', line 75

def load_jira_config jira_config
  @jira_url = jira_config['url']
  raise 'Must specify URL in config' if @jira_url.nil?

  @jira_email = jira_config['email']
  @jira_api_token = jira_config['api_token']
  @jira_personal_access_token = jira_config['personal_access_token']

  raise 'When specifying an api-token, you must also specify email' if @jira_api_token && !@jira_email

  if @jira_api_token && @jira_personal_access_token
    raise "You can't specify both an api-token and a personal-access-token. They don't work together."
  end

  @cookies = (jira_config['cookies'] || []).collect { |key, value| "#{key}=#{value}" }.join(';')
end

#make_curl_command(url:, method: 'GET') ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/jirametrics/jira_gateway.rb', line 92

def make_curl_command url:, method: 'GET'
  command = +''
  command << 'curl'
  command << ' -L' # follow redirects
  command << ' -s' # silent
  command << ' -k' if @ignore_ssl_errors # insecure
  command << " --cookie #{@cookies.inspect}" unless @cookies.empty?
  command << " --user #{@jira_email}:#{@jira_api_token}" if @jira_api_token
  command << " -H \"Authorization: Bearer #{@jira_personal_access_token}\"" if @jira_personal_access_token
  command << " --request #{method}"
  if method == 'POST'
    command << ' --data @-'
    command << ' --header "Content-Type: application/json"'
  end
  command << ' --header "Accept: application/json"'
  command << ' --show-error --fail' # Better diagnostics when the server returns an error
  command << " --url \"#{url}\""
  command
end

#parse_response(command:, result:) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/jirametrics/jira_gateway.rb', line 54

def parse_response command:, result:
  begin
    json = JSON.parse(result)
  rescue # rubocop:disable Style/RescueStandardError
    message = "Unable to parse results from #{sanitize_message(command)}"
    @file_system.error message, more: result
    raise message
  end

  raise "Download failed with: #{JSON.pretty_generate(json)}" unless json_successful?(json)

  json
end

#post_request(relative_url:, payload:) ⇒ Object



19
20
21
22
# File 'lib/jirametrics/jira_gateway.rb', line 19

def post_request relative_url:, payload:
  command = make_curl_command url: "#{@jira_url}#{relative_url}", method: 'POST'
  exec_and_parse_response command: command, stdin_data: payload
end

#sanitize_message(message) ⇒ Object



68
69
70
71
72
73
# File 'lib/jirametrics/jira_gateway.rb', line 68

def sanitize_message message
  token = @jira_api_token || @jira_personal_access_token
  return message unless token # cookie based authentication

  message.gsub(token, '[API_TOKEN]')
end