gitlab_support_readiness 1.0.41 → 1.0.42

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/lib/support_readiness/mailgun/client.rb +2 -1
  3. data/lib/support_readiness/mailgun/emails.rb +1 -1
  4. data/lib/support_readiness/support_super_form_processor/create_article.rb +375 -0
  5. data/lib/support_readiness/support_super_form_processor/create_macro.rb +183 -0
  6. data/lib/support_readiness/support_super_form_processor/edit_macro.rb +161 -0
  7. data/lib/support_readiness/support_super_form_processor/enable_us_government.rb +236 -0
  8. data/lib/support_readiness/support_super_form_processor/global_ir_dotcom_subscriptions_billing_entity_change.rb +218 -0
  9. data/lib/support_readiness/support_super_form_processor/global_ir_dotcom_subscriptions_extension.rb +238 -0
  10. data/lib/support_readiness/support_super_form_processor/global_ir_dotcom_subscriptions_investigate.rb +238 -0
  11. data/lib/support_readiness/support_super_form_processor/global_ir_dotcom_subscriptions_link.rb +213 -0
  12. data/lib/support_readiness/support_super_form_processor/global_ir_dotcom_subscriptions_nfr.rb +224 -0
  13. data/lib/support_readiness/support_super_form_processor/global_ir_dotcom_subscriptions_reset_seat_qsr.rb +194 -0
  14. data/lib/support_readiness/support_super_form_processor/global_ir_dotcom_trials_edit.rb +198 -0
  15. data/lib/support_readiness/support_super_form_processor/global_ir_dotcom_trials_extension.rb +228 -0
  16. data/lib/support_readiness/support_super_form_processor/global_ir_dotcom_trials_over_plan.rb +219 -0
  17. data/lib/support_readiness/support_super_form_processor/global_ir_hackerone_license.rb +172 -0
  18. data/lib/support_readiness/support_super_form_processor/global_ir_oem_license.rb +241 -0
  19. data/lib/support_readiness/support_super_form_processor/global_ir_order_management.rb +267 -0
  20. data/lib/support_readiness/support_super_form_processor/global_ir_other.rb +137 -0
  21. data/lib/support_readiness/support_super_form_processor/global_ir_provison_failure.rb +179 -0
  22. data/lib/support_readiness/support_super_form_processor/global_ir_sm_subscriptions_did_not_receive.rb +191 -0
  23. data/lib/support_readiness/support_super_form_processor/global_ir_sm_subscriptions_multiyear.rb +188 -0
  24. data/lib/support_readiness/support_super_form_processor/global_ir_sm_subscriptions_nfr.rb +215 -0
  25. data/lib/support_readiness/support_super_form_processor/global_ir_sm_subscriptions_resend.rb +188 -0
  26. data/lib/support_readiness/support_super_form_processor/global_ir_sm_subscriptions_scl.rb +194 -0
  27. data/lib/support_readiness/support_super_form_processor/global_ir_sm_subscriptions_temp.rb +234 -0
  28. data/lib/support_readiness/support_super_form_processor/global_ir_sm_trials_edit.rb +203 -0
  29. data/lib/support_readiness/support_super_form_processor/global_ir_sm_trials_extension.rb +233 -0
  30. data/lib/support_readiness/support_super_form_processor/global_ir_sm_trials_new.rb +223 -0
  31. data/lib/support_readiness/support_super_form_processor/global_ir_wider_community_license.rb +247 -0
  32. data/lib/support_readiness/support_super_form_processor/global_set_collaboration_id.rb +151 -0
  33. data/lib/support_readiness/support_super_form_processor/global_set_org_ase.rb +293 -0
  34. data/lib/support_readiness/support_super_form_processor/global_toggle_escalation.rb +142 -0
  35. data/lib/support_readiness/support_super_form_processor/gratis_support_extension.rb +247 -0
  36. data/lib/support_readiness/support_super_form_processor/gratis_support_former_customer.rb +288 -0
  37. data/lib/support_readiness/support_super_form_processor/gratis_support_migration.rb +238 -0
  38. data/lib/support_readiness/support_super_form_processor/gratis_support_other.rb +221 -0
  39. data/lib/support_readiness/support_super_form_processor/gratis_support_prospect.rb +288 -0
  40. data/lib/support_readiness/support_super_form_processor/gratis_support_upgrade.rb +298 -0
  41. data/lib/support_readiness/support_super_form_processor/namespace_availability.rb +213 -0
  42. data/lib/support_readiness/support_super_form_processor/pd_shadow_modification.rb +189 -0
  43. data/lib/support_readiness/support_super_form_processor/sa_request_for_support.rb +214 -0
  44. data/lib/support_readiness/support_super_form_processor/shared.rb +518 -0
  45. data/lib/support_readiness/support_super_form_processor/team_member_license.rb +144 -0
  46. data/lib/support_readiness/support_super_form_processor/two_fa_exemption.rb +260 -0
  47. data/lib/support_readiness/support_super_form_processor/usgov_ir_order_management.rb +252 -0
  48. data/lib/support_readiness/support_super_form_processor/usgov_ir_other.rb +136 -0
  49. data/lib/support_readiness/support_super_form_processor/usgov_ir_sm_subs_did_not_receive.rb +162 -0
  50. data/lib/support_readiness/support_super_form_processor/usgov_ir_sm_subs_multiyear.rb +159 -0
  51. data/lib/support_readiness/support_super_form_processor/usgov_ir_sm_subs_nfr.rb +196 -0
  52. data/lib/support_readiness/support_super_form_processor/usgov_ir_sm_subs_resend.rb +159 -0
  53. data/lib/support_readiness/support_super_form_processor/usgov_ir_sm_subs_scl.rb +160 -0
  54. data/lib/support_readiness/support_super_form_processor/usgov_ir_sm_subs_temp.rb +219 -0
  55. data/lib/support_readiness/support_super_form_processor/usgov_ir_sm_trials_edit.rb +189 -0
  56. data/lib/support_readiness/support_super_form_processor/usgov_ir_sm_trials_extension.rb +219 -0
  57. data/lib/support_readiness/support_super_form_processor/usgov_ir_sm_trials_new.rb +209 -0
  58. data/lib/support_readiness/support_super_form_processor/usgov_set_collaboration_id.rb +151 -0
  59. data/lib/support_readiness/support_super_form_processor/usgov_set_org_ase.rb +295 -0
  60. data/lib/support_readiness/support_super_form_processor.rb +67 -0
  61. data/lib/support_readiness.rb +1 -0
  62. metadata +59 -2
@@ -0,0 +1,298 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Defines the module Readiness.
4
+ module Readiness
5
+ # Defines the module SupportSuperFormProcessor
6
+ module SupportSuperFormProcessor
7
+ ##
8
+ # Defines the class GratisSupportUpgrade within the module {Readiness::Zendesk}.
9
+ #
10
+ # @author Jason Colyer
11
+ # @since 1.0.42
12
+ class GratisSupportUpgrade < Readiness::Client
13
+ ##
14
+ # Process a Gratis Support Upgrade request
15
+ #
16
+ # @author Jason Colyer
17
+ # @since 1.0.42
18
+ def self.process!(gitlab_client, gitlab_admin_client, sfdc_client)
19
+ @gitlab_client = gitlab_client
20
+ @gitlab_admin_client = gitlab_admin_client
21
+ @sfdc_client = sfdc_client
22
+ requester
23
+ checks
24
+ issue = Readiness::GitLab::Issues.new
25
+ issue.title = 'Gratis Support Request for an Upgrade Offerring'
26
+ issue.description = message
27
+ create = Readiness::GitLab::Issues.create!(@gitlab_client, project, issue)
28
+ puts "Issue created: #{create.web_url}"
29
+ exit 0
30
+ end
31
+
32
+ ##
33
+ # Sets the global variable errors
34
+ #
35
+ # @author Jason Colyer
36
+ # @since 1.0.42
37
+ def self.errors
38
+ @errors ||= []
39
+ end
40
+
41
+ ##
42
+ # Perform the checks for this request
43
+ #
44
+ # @author Jason Colyer
45
+ # @since 1.0.42
46
+ def self.checks
47
+ if sfdc_account.nil?
48
+ errors.push('Invalid SFDC account given')
49
+ else
50
+ errors.push('Incorrect SFDC account type') if sfdc_account.Type != 'Customer'
51
+ end
52
+ errors.push('Invalid SFDC opportunity given') if sfdc_opportunity.nil?
53
+ errors.push('Invalid manager handle given') if manager.nil?
54
+ end
55
+
56
+ ##
57
+ # Sets the global variable requester
58
+ #
59
+ # @author Jason Colyer
60
+ # @since 1.0.42
61
+ def self.requester
62
+ @requester ||= Readiness::SupportSuperFormProcessor::Shared.gitlab_user_check(@gitlab_admin_client, requester_email)
63
+ end
64
+
65
+ ##
66
+ # Sets the global variable requester_email
67
+ #
68
+ # @author Jason Colyer
69
+ # @since 1.0.42
70
+ def self.requester_email
71
+ @requester_email ||= ENV.fetch('REQUESTER_EMAIL')
72
+ end
73
+
74
+ ##
75
+ # Sets the global variable project
76
+ #
77
+ # @author Jason Colyer
78
+ # @since 1.0.42
79
+ def self.project
80
+ @project ||= Readiness::GitLab::Projects.find!(@gitlab_client, 12811526)
81
+ end
82
+
83
+ ##
84
+ # Sets the global variable sfdc_account_id
85
+ #
86
+ # @author Jason Colyer
87
+ # @since 1.0.42
88
+ def self.sfdc_account_id
89
+ @sfdc_account_id ||= determine_sfdc_account_id
90
+ end
91
+
92
+ ##
93
+ # Determines the SFDC Account ID based off of the link given
94
+ #
95
+ # @author Jason Colyer
96
+ # @since 1.0.42
97
+ def self.determine_sfdc_account_id
98
+ link = ENV.fetch('GRATUS_SUPPORT_SFDC_ACCOUNT')
99
+ return link.split('/')[-2] if link =~ /lightning/
100
+
101
+ link.split('/').last
102
+ end
103
+
104
+ ##
105
+ # Sets the global variable sfdc_opportunity_id
106
+ #
107
+ # @author Jason Colyer
108
+ # @since 1.0.42
109
+ def self.sfdc_opportunity_id
110
+ @sfdc_account_id ||= determine_sfdc_opportunity_id
111
+ end
112
+
113
+ ##
114
+ # Determines the SFDC Opportunity ID based off of the link given
115
+ #
116
+ # @author Jason Colyer
117
+ # @since 1.0.42
118
+ def self.determine_sfdc_opportunity_id
119
+ link = ENV.fetch('GRATIS_SUPPORT_SFDC_OPPORTUNITY')
120
+ return link.split('/')[-2] if link =~ /lightning/
121
+
122
+ link.split('/').last
123
+ end
124
+
125
+ ##
126
+ # Sets the global variable sfdc_account
127
+ #
128
+ # @author Jason Colyer
129
+ # @since 1.0.42
130
+ def self.sfdc_account
131
+ @sfdc_account ||= fetch_sfdc_account
132
+ end
133
+
134
+ ##
135
+ # Gets the SFDC Account information
136
+ #
137
+ # @author Jason Colyer
138
+ # @since 1.0.42
139
+ def self.fetch_sfdc_account
140
+ query = Readiness::Salesforce::Queries.new(account_query)
141
+ results = Readiness::Salesforce::Queries.run!(@sfdc_client, query)
142
+ results.first
143
+ end
144
+
145
+ ##
146
+ # Sets the global variable sfdc_opportunity
147
+ #
148
+ # @author Jason Colyer
149
+ # @since 1.0.42
150
+ def self.sfdc_opportunity
151
+ @sfdc_opportunity ||= fetch_sfdc_opportunity
152
+ end
153
+
154
+ ##
155
+ # Gets the SFDC Opportunity information
156
+ #
157
+ # @author Jason Colyer
158
+ # @since 1.0.42
159
+ def self.fetch_sfdc_opportunity
160
+ query = Readiness::Salesforce::Queries.new(opportunity_query)
161
+ results = Readiness::Salesforce::Queries.run!(@sfdc_client, query)
162
+ results.first
163
+ end
164
+
165
+ ##
166
+ # Sets the global variable justification
167
+ #
168
+ # @author Jason Colyer
169
+ # @since 1.0.42
170
+ def self.justification
171
+ @justification ||= ENV.fetch('GRATUS_SUPPORT_JUSTIFICATION')
172
+ end
173
+
174
+ ##
175
+ # Sets the global variable current_plan
176
+ #
177
+ # @author Jason Colyer
178
+ # @since 1.0.42
179
+ def self.current_plan
180
+ @current_plan ||= ENV.fetch('GRATIS_SUPPORT_CURRENT_SUB')
181
+ end
182
+
183
+ ##
184
+ # Sets the global variable plan
185
+ #
186
+ # @author Jason Colyer
187
+ # @since 1.0.42
188
+ def self.plan
189
+ @plan ||= ENV.fetch('GRATIS_SUPPORT_NEW_SUB')
190
+ end
191
+
192
+ ##
193
+ # Returns a SOQL query string to get Account info
194
+ #
195
+ # @author Jason Colyer
196
+ # @since 1.0.42
197
+ def self.account_query
198
+ <<~STRING
199
+ SELECT
200
+ Account.Account_ID_18__c,
201
+ Account.Name,
202
+ Account.Type
203
+ FROM Account
204
+ WHERE
205
+ Account.Account_ID_18__c = '#{sfdc_account_id}'
206
+ STRING
207
+ end
208
+
209
+ ##
210
+ # Returns a SOQL query string to get Opportunity info
211
+ #
212
+ # @author Jason Colyer
213
+ # @since 1.0.42
214
+ def self.opportunity_query
215
+ <<~STRING
216
+ SELECT
217
+ Opportunity.Id,
218
+ Opportunity.ARR__c
219
+ FROM Opportunity
220
+ WHERE
221
+ Opportunity.Id = '#{sfdc_opportunity_id}'
222
+ STRING
223
+ end
224
+
225
+ ##
226
+ # Returns a string for the errors block
227
+ #
228
+ # @author Jason Colyer
229
+ # @since 1.0.42
230
+ def self.errors_block
231
+ return '' if errors.count.zero?
232
+
233
+ <<~STRING
234
+ ## Attention @jcolyer and @#{requester.username}
235
+
236
+ The following problems were detected in the form submission:
237
+
238
+ #{errors.map { |e| "- #{e}" }.join("\n")}
239
+
240
+ These will need to be corrected to proceed. Please communicate via issue comments to work this out.
241
+ STRING
242
+ end
243
+
244
+ ##
245
+ # Returns a string for the issue body
246
+ #
247
+ # @author Jason Colyer
248
+ # @since 1.0.42
249
+ def self.message
250
+ <<~STRING
251
+ ## Gratis Support Request for an Upgrade Offerring
252
+
253
+ - Requester: @#{requester.username}
254
+ - Approver: @#{manager.nil? ? manager_handle : manager.username}
255
+ - SFDC Account: #{sfdc_account.nil? ? sfdc_account_id : sfdc_account.Account_ID_18__c}
256
+ - SFDC Opportunity: #{sfdc_opportunity.nil? ? sfdc_opportunity_id : sfdc_opportunity.Id}
257
+ - ARR: #{sfdc_opportunity.nil? ? 'Unknown' : sfdc_opportunity.ARR__c}
258
+ - Plan customer is currently on: #{current_plan}
259
+ - Plan customer is trialing: #{plan}
260
+ - Justification:
261
+
262
+ ```
263
+ #{justification}
264
+ ```
265
+
266
+ #{errors_block}
267
+
268
+ ## @#{requester.username} TODO
269
+
270
+ - [ ] Look over the issue and confirm all data is correct
271
+ - [ ] Work with the approver on their TODO section
272
+
273
+ ## @#{manager.nil? ? manager_handle : manager.username} TODO
274
+
275
+ - [ ] Review the request and check this box to approve the request
276
+ - If you are not approving it, please add a comment explaining why and close the issue.
277
+ - [ ] Add a comment signaling your approval (this let's the assignees know the issue is ready to proceed).
278
+ - Please note your comment must explicitly say that you approve this request. If that is not explict, you may be asked to state the approval explicitly.
279
+
280
+ ## Support Readiness TODO
281
+
282
+ - [ ] Review the above information for accuracy
283
+ - [ ] Review [our documentation](https://handbook.gitlab.com/handbook/support/readiness/operations/docs/policies/gratis_support/#extensions) for this and ensure it passes all required checks/validations
284
+ - [ ] Ensure the approver has checked the above box to signal approval
285
+ - [ ] Implement this as per [our documentation](https://handbook.gitlab.com/handbook/support/readiness/operations/docs/policies/gratis_support/#extensions)
286
+
287
+ /assign @jcolyer
288
+
289
+ /cc @#{requester.username} @#{manager.nil? ? manager_handle : manager.username}
290
+
291
+ /label ~"Readiness Priority::Current Quarter" ~"Readiness::Consulting" ~"Zendesk::Global" ~"Support-Ops-Category::Orgs and Users" ~"Gratis Support Request::Upgrade Offerring"
292
+
293
+ /due in 72 hours
294
+ STRING
295
+ end
296
+ end
297
+ end
298
+ end
@@ -0,0 +1,213 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Defines the module Readiness.
4
+ module Readiness
5
+ # Defines the module SupportSuperFormProcessor
6
+ module SupportSuperFormProcessor
7
+ ##
8
+ # Defines the class NamespaceAvailability within the module {Readiness::Zendesk}.
9
+ #
10
+ # @author Jason Colyer
11
+ # @since 1.0.42
12
+ class NamespaceAvailability < Readiness::Client
13
+ ##
14
+ # Process a Namesquatting Availability check request
15
+ #
16
+ # @author Jason Colyer
17
+ # @since 1.0.42
18
+ def self.process!(client, admin_client)
19
+ @gitlab_client = client
20
+ @gitlab_admin_client = admin_client
21
+ requester
22
+ namespace_does_not_exist unless Readiness::GitLab::Namespaces.exists?(@gitlab_admin_client, namespace_to_check)
23
+ namespace_not_available if Readiness::GitLab::Namespaces.is_paid?(@gitlab_admin_client, namespace)
24
+ user_checks if namespace.kind. == 'user'
25
+ group_checks if namespace.kind == 'group'
26
+ end
27
+
28
+ ##
29
+ # Perform the user checks for a Namesquatting Availability check request
30
+ #
31
+ # @author Jason Colyer
32
+ # @since 1.0.42
33
+ def self.user_checks
34
+ search = Readiness::GitLab::Users.search_by_username(@gitlab_admin_client, namespace_to_check)
35
+ user = search.detect { |s| s.username.downcase == namespace_to_check.downcase }
36
+ namespace_may_be_available if user.confirmed_at.nil? && user_created_recently?(user)
37
+ namespace_not_available if (Date.today - 2.years) < Date.parse(user.current_sign_in_at)
38
+ namespace_not_available if Readiness::GitLab::Users.only_maintainer?(@gitlab_admin_client, user)
39
+ namespace_may_be_available
40
+ end
41
+
42
+ ##
43
+ # Determines if a user was created recently
44
+ #
45
+ # @author Jason Colyer
46
+ # @since 1.0.42
47
+ # @return [Boolean]
48
+ def self.user_created_recently?(user)
49
+ (Date.today - 90.days) < Date.parse(user.created_at)
50
+ end
51
+
52
+ ##
53
+ # Perform the group checks for a Namesquatting Availability check request
54
+ #
55
+ # @author Jason Colyer
56
+ # @since 1.0.42
57
+ def self.group_checks
58
+ group = Readiness::GitLab::Groups.new
59
+ group.id = namespace.id
60
+ projects = Readiness::GitLab::Groups.projects(client, group, ["archived=false", "include_subgroups=true"])
61
+ detection = projects.detect { |p| (Date.today - 2.years) < Date.parse(p.last_activity_at) }
62
+ namespace_may_be_available if detection.nil?
63
+ namespace_not_available
64
+ end
65
+
66
+ ##
67
+ # Sets the global variable requester
68
+ #
69
+ # @author Jason Colyer
70
+ # @since 1.0.42
71
+ def self.requester
72
+ @requester ||= Readiness::SupportSuperFormProcessor::Shared.gitlab_user_check(@gitlab_admin_client, requester_email)
73
+ end
74
+
75
+ ##
76
+ # Sets the global variable namespace_to_check
77
+ #
78
+ # @author Jason Colyer
79
+ # @since 1.0.42
80
+ def self.namespace_to_check
81
+ @namespace_to_check ||= ENV.fetch('NAMESPACE_CHECK_NAMESPACE')
82
+ end
83
+
84
+ ##
85
+ # Sets the global variable requester_email
86
+ #
87
+ # @author Jason Colyer
88
+ # @since 1.0.42
89
+ def self.requester_email
90
+ @requester_email ||= ENV.fetch('REQUESTER_EMAIL')
91
+ end
92
+
93
+ ##
94
+ # Sets the global variable project
95
+ #
96
+ # @author Jason Colyer
97
+ # @since 1.0.42
98
+ def self.project
99
+ @project ||= Readiness::GitLab::Projects.find!(@gitlab_client, 12811526)
100
+ end
101
+
102
+ ##
103
+ # Sets the global variable namespace
104
+ #
105
+ # @author Jason Colyer
106
+ # @since 1.0.42
107
+ def self.namespace
108
+ @namespace ||= Readiness::GitLab::Namespaces.find!(@gitlab_admin_client, namespace_to_check)
109
+ end
110
+
111
+ ##
112
+ # Handles the case where the namespace does not exist
113
+ #
114
+ # @author Jason Colyer
115
+ # @since 1.0.42
116
+ def self.namespace_does_not_exist
117
+ issue = Readiness::GitLab::Issues.new
118
+ issue.title = "Namespace Availability Check - #{CGI.escape(namespace_to_check)}"
119
+ issue.description = namespace_does_not_exist_message
120
+ create = Readiness::GitLab::Issues.create!(@gitlab_client, project, issue)
121
+ puts "Issue created: #{create.web_url}"
122
+ exit 0
123
+ end
124
+
125
+ ##
126
+ # Handles the case where the namespace is not available
127
+ #
128
+ # @author Jason Colyer
129
+ # @since 1.0.42
130
+ def self.namespace_not_available
131
+ issue = Readiness::GitLab::Issues.new
132
+ issue.title = "Namespace Availability Check - #{CGI.escape(namespace_to_check)}"
133
+ issue.description = namespace_not_available_message
134
+ create = Readiness::GitLab::Issues.create!(@gitlab_client, project, issue)
135
+ puts "Issue created: #{create.web_url}"
136
+ exit 0
137
+ end
138
+
139
+ ##
140
+ # Handles the case where the namespace may be available
141
+ #
142
+ # @author Jason Colyer
143
+ # @since 1.0.42
144
+ def self.namespace_may_be_available
145
+ issue = Readiness::GitLab::Issues.new
146
+ issue.title = "Namespace Availability Check - #{CGI.escape(namespace_to_check)}"
147
+ issue.description = namespace_may_be_available_message
148
+ create = Readiness::GitLab::Issues.create!(@gitlab_client, project, issue)
149
+ puts "Issue created: #{create.web_url}"
150
+ exit 0
151
+ end
152
+
153
+ ##
154
+ # Returns the issue description for a case where the namespace is not available
155
+ #
156
+ # @author Jason Colyer
157
+ # @since 1.0.42
158
+ def self.namespace_not_available_message
159
+ <<~STRING
160
+ ## Namespace Availability Check for #{CGI.escape(namespace_to_check)}
161
+
162
+ Greetings @#{requester.username} !
163
+
164
+ We have looked into the availability of the namespace #{CGI.escape(namespace_to_check)} and have determined it will not be available for release at this time.
165
+
166
+ /label ~"AutomatedRequests::Namespace Availability Check"
167
+
168
+ /assign @#{requester.username}
169
+ STRING
170
+ end
171
+
172
+ ##
173
+ # Returns the issue description for a case where the namespace does not exist
174
+ #
175
+ # @author Jason Colyer
176
+ # @since 1.0.42
177
+ def self.namespace_does_not_exist_message
178
+ <<~STRING
179
+ ## Namespace Availability Check for #{CGI.escape(namespace_to_check)}
180
+
181
+ Greetings @#{requester.username} !
182
+
183
+ We have looked into the availability of the namespace #{CGI.escape(namespace_to_check)} and have been unable to locate the namespace on gitlab.com. This would mean it is not currently in use at all and should be available at this exact moment in time.
184
+
185
+ /label ~"AutomatedRequests::Namespace Availability Check"
186
+
187
+ /assign @#{requester.username}
188
+ STRING
189
+ end
190
+
191
+ ##
192
+ # Returns the issue description for a case where the namespace may be available
193
+ #
194
+ # @author Jason Colyer
195
+ # @since 1.0.42
196
+ def self.namespace_may_be_available_message
197
+ <<~STRING
198
+ ## Namespace Availability Check for #{CGI.escape(namespace_to_check)}
199
+
200
+ Greetings @#{requester.username} !
201
+
202
+ We have looked into the availability of the namespace #{CGI.escape(namespace_to_check)} and have determined it _may_ be available for release at this time.
203
+
204
+ Please note this only reflects the _possibility_ of release _at this exact time_. Any number of factors or events could change in the future to change this determination.
205
+
206
+ /label ~"AutomatedRequests::Namespace Availability Check"
207
+
208
+ /assign @#{requester.username}
209
+ STRING
210
+ end
211
+ end
212
+ end
213
+ end
@@ -0,0 +1,189 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Defines the module Readiness.
4
+ module Readiness
5
+ # Defines the module SupportSuperFormProcessor
6
+ module SupportSuperFormProcessor
7
+ ##
8
+ # Defines the class PagerdutyShadowModification within the module {Readiness::Zendesk}.
9
+ #
10
+ # @author Jason Colyer
11
+ # @since 1.0.42
12
+ class PagerdutyShadowModification < Readiness::Client
13
+ ##
14
+ # Process a Pagerduty Shadow Modification request
15
+ #
16
+ # @author Jason Colyer
17
+ # @since 1.0.42
18
+ def self.process!(gitlab_client, gitlab_admin_client, pagerduty_client)
19
+ @gitlab_client = gitlab_client
20
+ @gitlab_admin_client = gitlab_admin_client
21
+ @pagerduty_client = pagerduty_client
22
+ requester
23
+ pd_user = Readiness::Pagerduty::Users.find_by_email(@pagerduty_client, requester_email)
24
+ bad_pd_user if pd_user.nil?
25
+ schedule = Readiness::Pagerduty::Schedules.find!(@pagerduty_client, schedule_id)
26
+ layer = schedule.schedule_layers.detect { |l| l['name'] == "Layer #{layer_name}" }
27
+ if layer['users'].detect { |u| u['user']['id'] == pd_user.id }
28
+ type = 'remove'
29
+ if layer['users'].count == 1
30
+ layer['users'] = [{ user: { id: 'PRGFAO1', type: 'user_reference' }}]
31
+ else
32
+ layer['users'].delete_at(layer['users'].find_index { |u| u['user']['id'] == pd_user.id })
33
+ end
34
+ else
35
+ type = 'add'
36
+ if layer['users'].count == 1 && layer['users'].first['user']['id'] == 'PRGFAO1'
37
+ layer['users'] = [{ user: { id: pd_user.id, type: 'user_reference' }}]
38
+ else
39
+ layer['users'].push({ user: { id: pd_user.id, type: 'user_reference' }})
40
+ end
41
+ end
42
+ schedule.schedule_layers.each_with_index do |l, i|
43
+ schedule.schedule_layers[i] = layer if l['name'] == layer['name']
44
+ break if l['name'] == layer['name']
45
+ end
46
+ Readiness::Pagerduty::Schedules.update!(@pagerduty_client, schedule)
47
+ added if type == 'add'
48
+ removed if type == 'remove'
49
+ end
50
+
51
+ ##
52
+ # Creates an issue to indicate the requesterer doesn't have a PD user
53
+ #
54
+ # @author Jason Colyer
55
+ # @since 1.0.42
56
+ def self.bad_pd_user
57
+ issue = Readiness::GitLab::Issues.new
58
+ issue.title = "Invalid request regarding Pagerduty Shadow rotation"
59
+ issue.description = bad_user_message
60
+ create = Readiness::GitLab::Issues.create!(@gitlab_client, project, issue)
61
+ puts "Issue created: #{create.web_url}"
62
+ exit 0
63
+ end
64
+
65
+ ##
66
+ # Creates an issue to indicate being added
67
+ #
68
+ # @author Jason Colyer
69
+ # @since 1.0.42
70
+ def self.added
71
+ issue = Readiness::GitLab::Issues.new
72
+ issue.title = "Add to Pagerduty Shadow rotation"
73
+ issue.description = added_message
74
+ create = Readiness::GitLab::Issues.create!(@gitlab_client, project, issue)
75
+ puts "Issue created: #{create.web_url}"
76
+ exit 0
77
+ end
78
+
79
+ ##
80
+ # Creates an issue to indicate being removed
81
+ #
82
+ # @author Jason Colyer
83
+ # @since 1.0.42
84
+ def self.removed
85
+ issue = Readiness::GitLab::Issues.new
86
+ issue.title = "Remove from Pagerduty Shadow rotation"
87
+ issue.description = removed_message
88
+ create = Readiness::GitLab::Issues.create!(@gitlab_client, project, issue)
89
+ puts "Issue created: #{create.web_url}"
90
+ exit 0
91
+ end
92
+
93
+ ##
94
+ # Sets the global variable requester
95
+ #
96
+ # @author Jason Colyer
97
+ # @since 1.0.42
98
+ def self.requester
99
+ @requester ||= Readiness::SupportSuperFormProcessor::Shared.gitlab_user_check(@gitlab_admin_client, requester_email)
100
+ end
101
+
102
+ ##
103
+ # Sets the global variable requester_email
104
+ #
105
+ # @author Jason Colyer
106
+ # @since 1.0.42
107
+ def self.requester_email
108
+ @requester_email ||= ENV.fetch('REQUESTER_EMAIL')
109
+ end
110
+
111
+ ##
112
+ # Sets the global variable project
113
+ #
114
+ # @author Jason Colyer
115
+ # @since 1.0.42
116
+ def self.project
117
+ @project ||= Readiness::GitLab::Projects.find!(@gitlab_client, 12811526)
118
+ end
119
+
120
+ ##
121
+ # Sets the global schedule_id
122
+ #
123
+ # @author Jason Colyer
124
+ # @since 1.0.42
125
+ def self.schedule_id
126
+ @schedule_id ||= ENV.fetch('PD_SHADOW_SCHEDULE')
127
+ end
128
+
129
+ ##
130
+ # Sets the global layer_name
131
+ #
132
+ # @author Jason Colyer
133
+ # @since 1.0.42
134
+ def self.layer_name
135
+ @layer_name ||= ENV.fetch('PD_SHADOW_LAYER')
136
+ end
137
+
138
+ def self.bad_user_message
139
+ <<~STRING
140
+ ## Invalid request regarding Pagerduty Shadow rotation
141
+
142
+ Greetings @#{requester.username} !
143
+
144
+ We received a request to add or remove you from a Pagerduty shadow rotation.
145
+
146
+ We were unable to proceed as a PD user using your email, #{requester_email}, was not found
147
+
148
+ Please double check your request to ensure the email you used matches the email in Pagerduty.
149
+
150
+ Once that has been rectified, please submit a new request.
151
+
152
+ /label ~"AutomatedRequests::Bad Pagerduty User"
153
+
154
+ /assign @#{requester.username}
155
+ STRING
156
+ end
157
+
158
+ def self.added_message
159
+ <<~STRING
160
+ ## Add to Pagerduty Shadow rotation
161
+
162
+ Greetings @#{requester.username} !
163
+
164
+ We received a request to add you to a Pagerduty shadow rotation. This is to let you know it has been completed at this time.
165
+
166
+ Do note you are at the top of the list, so your oncall for that would start this week.
167
+
168
+ /label ~"AutomatedRequests::Pagerduty"
169
+
170
+ /assign @#{requester.username}
171
+ STRING
172
+ end
173
+
174
+ def self.removed_message
175
+ <<~STRING
176
+ ## Remove from Pagerduty Shadow rotation
177
+
178
+ Greetings @#{requester.username} !
179
+
180
+ We received a request to remove you from a Pagerduty shadow rotation. This is to let you know it has been completed at this time.
181
+
182
+ /label ~"AutomatedRequests::Pagerduty"
183
+
184
+ /assign @#{requester.username}
185
+ STRING
186
+ end
187
+ end
188
+ end
189
+ end