Module: AbideDevUtils::Jira

Defined in:
lib/abide_dev_utils/jira.rb

Defined Under Namespace

Classes: Dummy

Constant Summary collapse

ERRORS =
AbideDevUtils::Errors::Jira
COV_PARENT_SUMMARY_PREFIX =
'::BENCHMARK:: '
COV_CHILD_SUMMARY_PREFIX =
'::CONTROL:: '

Class Method Summary collapse

Class Method Details

.all_project_issues_attrs(project) ⇒ Object



35
36
37
38
# File 'lib/abide_dev_utils/jira.rb', line 35

def self.all_project_issues_attrs(project)
  raw_issues = project.issues
  raw_issues.collect(&:attrs)
end

.bulk_new_issue(client, project, summaries, dry_run: false) ⇒ Object

This should probably be threaded in the future



58
59
60
# File 'lib/abide_dev_utils/jira.rb', line 58

def self.bulk_new_issue(client, project, summaries, dry_run: false)
  summaries.each { |s| new_issue(client, project, s, dry_run: dry_run) }
end

.bulk_new_subtask(client, issue, summaries, dry_run: false) ⇒ Object



81
82
83
84
85
# File 'lib/abide_dev_utils/jira.rb', line 81

def self.bulk_new_subtask(client, issue, summaries, dry_run: false)
  summaries.each do |s|
    new_subtask(client, issue, s, dry_run: dry_run)
  end
end

.client(options: {}) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
# File 'lib/abide_dev_utils/jira.rb', line 87

def self.client(options: {})
  opts = merge_options(options)
  return client_from_prompts if opts.empty?

  opts[:username] = AbideDevUtils::Prompt.username if opts[:username].nil?
  opts[:password] = AbideDevUtils::Prompt.password if opts[:password].nil?
  opts[:site] = AbideDevUtils::Prompt.single_line('Jira URL') if opts[:site].nil?
  opts[:context_path] = '' if opts[:context_path].nil?
  opts[:auth_type] = :basic if opts[:auth_type].nil?
  JIRA::Client.new(opts)
end

.client_from_prompts(http_debug: false) ⇒ Object



99
100
101
102
103
104
105
106
107
108
# File 'lib/abide_dev_utils/jira.rb', line 99

def self.client_from_prompts(http_debug: false)
  options = {}
  options[:username] = AbideDevUtils::Prompt.username
  options[:password] = AbideDevUtils::Prompt.password
  options[:site] = AbideDevUtils::Prompt.single_line('Jira URL')
  options[:context_path] = ''
  options[:auth_type] = :basic
  options[:http_debug] = http_debug
  JIRA::Client.new(options)
end

.configObject



182
183
184
# File 'lib/abide_dev_utils/jira.rb', line 182

def self.config
  AbideDevUtils::Config.config_section(:jira)
end

.issue(client, issue) ⇒ Object



19
20
21
# File 'lib/abide_dev_utils/jira.rb', line 19

def self.issue(client, issue)
  client.Issue.find(issue)
end

.issuetype(client, id) ⇒ Object



27
28
29
# File 'lib/abide_dev_utils/jira.rb', line 27

def self.issuetype(client, id)
  client.Issuetype.find(id)
end

.merge_options(options) ⇒ Object

progress = AbideDevUtils::Output.progress(title: “#dr_prefixCreating Tasks”, total: nil)

v.each do |s|


178
179
180
# File 'lib/abide_dev_utils/jira.rb', line 178

def self.merge_options(options)
  config.merge(options)
end

.myself(client) ⇒ Object



23
24
25
# File 'lib/abide_dev_utils/jira.rb', line 23

def self.myself(client)
  client.User.myself
end

.new_issue(client, project, summary, dry_run: false) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/abide_dev_utils/jira.rb', line 40

def self.new_issue(client, project, summary, dry_run: false)
  if dry_run
    sleep(0.2)
    return Dummy.new
  end
  fields = {}
  fields['summary'] = summary
  fields['project'] = project(client, project)
  fields['reporter'] = myself(client)
  fields['issuetype'] = issuetype(client, '3')
  fields['priority'] = priority(client, '6')
  issue = client.Issue.build
  raise ERRORS::CreateIssueError, issue.attrs unless issue.save({ 'fields' => fields })

  issue
end

.new_issues_from_coverage(client, project, report, dry_run: false) ⇒ Object



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/abide_dev_utils/jira.rb', line 116

def self.new_issues_from_coverage(client, project, report, dry_run: false)
  dr_prefix = dry_run ? 'DRY RUN: ' : ''
  i_attrs = all_project_issues_attrs(project)
  rep_sums = summaries_from_coverage_report(report)
  rep_sums.each do |k, v|
    next if summary_exist?(k, i_attrs)

    parent = new_issue(client, project.attrs['key'], k.to_s, dry_run: dry_run)
    AbideDevUtils::Output.simple("#{dr_prefix}Created parent issue #{k}")
    parent_issue = issue(client, parent.attrs['key']) unless parent.respond_to?(:dummy)
    AbideDevUtils::Output.simple("#{dr_prefix}Creating subtasks, this can take a while...")
    progress = AbideDevUtils::Output.progress(title: "#{dr_prefix}Creating Subtasks", total: nil)
    v.each do |s|
      next if summary_exist?(s, i_attrs)

      progress.title = "#{dr_prefix}#{s}"
      new_subtask(client, parent_issue, s, dry_run: dry_run)
      progress.increment
    end
  end
end

.new_issues_from_xccdf(client, project, xccdf_path, dry_run: false) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/abide_dev_utils/jira.rb', line 138

def self.new_issues_from_xccdf(client, project, xccdf_path, dry_run: false)
  dr_prefix = dry_run ? 'DRY RUN: ' : ''
  i_attrs = all_project_issues_attrs(project)

  xccdf = AbideDevUtils::XCCDF::Benchmark.new(xccdf_path)

  summaries = summaries_from_xccdf(xccdf)
  summaries.each do |profile_summary, control_summaries|
    if summary_exist?(profile_summary, i_attrs)
      AbideDevUtils::Output.simple("#{dr_prefix}Skipping #{profile_summary} as it already exists")
      next
    end

    parent = new_issue(client, project.attrs['key'], profile_summary, dry_run: dry_run)
    AbideDevUtils::Output.simple("#{dr_prefix}Created parent issue #{profile_summary}")
    parent_issue = issue(client, parent.attrs['key']) unless parent.respond_to?(:dummy)
    AbideDevUtils::Output.simple("#{dr_prefix}Creating subtasks, this can take a while...")
    progress = AbideDevUtils::Output.progress(title: "#{dr_prefix}Creating Subtasks", total: nil)
    control_summaries.each do |control_summary|
      next if summary_exist?(control_summary, i_attrs)

      progress.title = "#{dr_prefix}#{control_summary}"
      new_subtask(client, parent_issue, control_summary, dry_run: dry_run)
      progress.increment
    end
    final_text = "#{dr_prefix}Created #{control_summaries.count} subtasks for #{profile_summary}"
    puts "\r\033[K#{final_text}\n"
  end
end

.new_subtask(client, issue, summary, dry_run: false) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/abide_dev_utils/jira.rb', line 62

def self.new_subtask(client, issue, summary, dry_run: false)
  if dry_run
    sleep(0.2)
    return Dummy.new
  end
  issue_fields = issue.attrs['fields']
  fields = {}
  fields['parent'] = issue
  fields['summary'] = summary
  fields['project'] = issue_fields['project']
  fields['reporter'] = myself(client)
  fields['issuetype'] = issuetype(client, '5')
  fields['priority'] = issue_fields['priority']
  subtask = client.Issue.build
  raise ERRORS::CreateSubtaskError, subtask.attrs unless subtask.save({ 'fields' => fields })

  subtask
end

.priority(client, id) ⇒ Object



31
32
33
# File 'lib/abide_dev_utils/jira.rb', line 31

def self.priority(client, id)
  client.Priority.find(id)
end

.project(client, project) ⇒ Object



15
16
17
# File 'lib/abide_dev_utils/jira.rb', line 15

def self.project(client, project)
  client.Project.find(project)
end

.project_from_prompts(http_debug: false) ⇒ Object



110
111
112
113
114
# File 'lib/abide_dev_utils/jira.rb', line 110

def self.project_from_prompts(http_debug: false)
  client = client_from_prompts(http_debug)
  project = AbideDevUtils::Prompt.single_line('Project').upcase
  client.Project.find(project)
end

.summaries_from_coverage_report(report) ⇒ Object

rubocop:disable Metrics/CyclomaticComplexity



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/abide_dev_utils/jira.rb', line 193

def self.summaries_from_coverage_report(report) # rubocop:disable Metrics/CyclomaticComplexity
  summaries = {}
  benchmark = nil
  report.each do |k, v|
    benchmark = v if k == 'benchmark'
    next unless k.match?(/^profile_/)

    parent_sum = k
    v.each do |sk, sv|
      next unless sk == 'uncovered'

      summaries[parent_sum] = sv.collect { |s| "#{COV_CHILD_SUMMARY_PREFIX}#{s}" }
    end
  end
  summaries.transform_keys { |k| "#{COV_PARENT_SUMMARY_PREFIX}#{benchmark}-#{k}"}
end

.summaries_from_xccdf(xccdf) ⇒ Object



210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/abide_dev_utils/jira.rb', line 210

def self.summaries_from_xccdf(xccdf)
  summaries = {}
  facter_os = xccdf.facter_benchmark.join('-')
  xccdf.profiles.each do |profile|
    summaries["#{COV_PARENT_SUMMARY_PREFIX}#{facter_os} - #{profile.level} #{profile.title}"] = profile.controls.collect do |control|
      summary = "#{COV_CHILD_SUMMARY_PREFIX}#{control.vulnid} - #{control.title}"
      if summary.length > 255
        summary = summary[0..251] + '...'
      end
      summary
    end
  end
  summaries
end

.summary_exist?(summary, issue_attrs) ⇒ Boolean

Returns:

  • (Boolean)


186
187
188
189
190
191
# File 'lib/abide_dev_utils/jira.rb', line 186

def self.summary_exist?(summary, issue_attrs)
  issue_attrs.each do |i|
    return true if i['fields']['summary'] == summary
  end
  false
end