gitlab_support_readiness 1.0.43 → 1.0.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/support_readiness/support_super_form_processor/global_set_collaboration_id.rb +1 -1
- data/lib/support_readiness/support_super_form_processor/global_set_org_ase.rb +1 -1
- data/lib/support_readiness/support_super_form_processor/global_toggle_escalation.rb +1 -1
- data/lib/support_readiness/support_super_form_processor/gratis_support_extension.rb +23 -5
- data/lib/support_readiness/support_super_form_processor/gratis_support_former_customer.rb +31 -0
- data/lib/support_readiness/support_super_form_processor/gratis_support_migration.rb +31 -0
- data/lib/support_readiness/support_super_form_processor/gratis_support_other.rb +31 -0
- data/lib/support_readiness/support_super_form_processor/gratis_support_prospect.rb +31 -0
- data/lib/support_readiness/support_super_form_processor/gratis_support_upgrade.rb +31 -0
- data/lib/support_readiness/support_super_form_processor/namespace_availability.rb +1 -1
- data/lib/support_readiness/support_super_form_processor/sa_request_for_support.rb +1 -1
- data/lib/support_readiness/support_super_form_processor/usgov_set_collaboration_id.rb +1 -1
- data/lib/support_readiness/support_super_form_processor/usgov_set_org_ase.rb +1 -1
- data/lib/support_readiness/support_super_form_processor.rb +1 -0
- data/lib/support_readiness/ticket_processor/account_blocked.rb +289 -0
- data/lib/support_readiness/ticket_processor/email_suppressions.rb +135 -0
- data/lib/support_readiness/ticket_processor/link_tagger.rb +102 -0
- data/lib/support_readiness/ticket_processor/locked_account.rb +53 -0
- data/lib/support_readiness/ticket_processor/namesquatting.rb +223 -0
- data/lib/support_readiness/ticket_processor/organization_notes.rb +308 -0
- data/lib/support_readiness/ticket_processor/star.rb +32 -0
- data/lib/support_readiness/ticket_processor/weighting.rb +121 -0
- data/lib/support_readiness/ticket_processor.rb +19 -0
- data/lib/support_readiness.rb +1 -0
- metadata +11 -2
@@ -0,0 +1,135 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Defines the module Readiness.
|
4
|
+
module Readiness
|
5
|
+
# Defines the module TicketProcessor
|
6
|
+
module TicketProcessor
|
7
|
+
##
|
8
|
+
# Defines the class EmailSuppressions within the module {Readiness::Zendesk}.
|
9
|
+
#
|
10
|
+
# @author Jason Colyer
|
11
|
+
# @since 1.0.44
|
12
|
+
class EmailSuppressions < Readiness::Client
|
13
|
+
##
|
14
|
+
# Process an Email Suppression request
|
15
|
+
#
|
16
|
+
# @author Jason Colyer
|
17
|
+
# @since 1.0.44
|
18
|
+
def self.process!(zendesk_client, mailgun_client, ticket_id)
|
19
|
+
@zendesk_client = zendesk_client
|
20
|
+
@mailgun_client = mailgun_client
|
21
|
+
@ticket_id = ticket_id
|
22
|
+
@ticket = Readiness::Zendesk::Tickets.find(@zendesk_client, @ticket_id)
|
23
|
+
puts 'No ticket found, so no org notes to add' if @ticket.is_a? Hash
|
24
|
+
exit 0 if @ticket.is_a? Hash
|
25
|
+
|
26
|
+
puts 'Ticket is closed, so no org notes to add' if @ticket.status == 'closed'
|
27
|
+
exit 0 if @ticket.status == 'closed'
|
28
|
+
|
29
|
+
@email = @ticket.custom_fields.detect { |t| t['id'] == 4413932829586 }['value']
|
30
|
+
return no_email_given if @email.nil?
|
31
|
+
|
32
|
+
bounce = Readiness::Mailgun::Bounces.find(@mailgun_client, @email)
|
33
|
+
if bounce.address.nil?
|
34
|
+
no_bounce_exists
|
35
|
+
else
|
36
|
+
Readiness::Mailgun::Bounces.delete!(@mailgun_client, bounce)
|
37
|
+
new_ticket = Readiness::Zendesk::Tickets.new
|
38
|
+
new_ticket.id = @ticket.id
|
39
|
+
new_ticket.comment = { body: suppression_removed_note(bounce), public: false }
|
40
|
+
Readiness::Zendesk::Tickets.update!(@zendesk_client, new_ticket)
|
41
|
+
new_ticket = Readiness::Zendesk::Tickets.new
|
42
|
+
new_ticket.id = @ticket.id
|
43
|
+
new_ticket.status = 'solved'
|
44
|
+
new_ticket.comment = { body: suppression_removed_comment, public: true }
|
45
|
+
new_ticket.custom_fields = [
|
46
|
+
{ id: 360020735259, value: 'stage-frt' }
|
47
|
+
]
|
48
|
+
Readiness::Zendesk::Tickets.update!(@zendesk_client, new_ticket)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.no_email_given
|
53
|
+
new_ticket = Readiness::Zendesk::Tickets.new
|
54
|
+
new_ticket.id = @ticket.id
|
55
|
+
new_ticket.comment = { body: no_email_given_comment, public: false }
|
56
|
+
new_ticket.custom_fields = [
|
57
|
+
{ id: 360020735259, value: 'stage-frt' }
|
58
|
+
]
|
59
|
+
Readiness::Zendesk::Tickets.update!(@zendesk_client, new_ticket)
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.no_bounce_exists
|
63
|
+
new_ticket = Readiness::Zendesk::Tickets.new
|
64
|
+
new_ticket.id = @ticket.id
|
65
|
+
new_ticket.status = 'pending'
|
66
|
+
new_ticket.comment = { body: no_bounce_exists_comment }
|
67
|
+
new_ticket.custom_fields = [
|
68
|
+
{ id: 360020735259, value: 'stage-frt' }
|
69
|
+
]
|
70
|
+
Readiness::Zendesk::Tickets.update!(@zendesk_client, new_ticket)
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.no_email_given_comment
|
74
|
+
<<~STRING
|
75
|
+
We were unable to check for email suppressions on this ticket as the value of the `Impacted email address` is blank.
|
76
|
+
|
77
|
+
Please do the following to correct this and have this ticket re-autoworked:
|
78
|
+
|
79
|
+
- Please review the ticket and correct the field 'Impacted email address' to have a valid value
|
80
|
+
- Remove any of the following tags:
|
81
|
+
- `autowork_no_confirmation_email`
|
82
|
+
- `autowork_forgot_password`
|
83
|
+
- `autowork_notification_emails`
|
84
|
+
|
85
|
+
Make sure to save the update on the ticket. This should re-trigger the autowork script for you.
|
86
|
+
STRING
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.no_bounce_exists_comment
|
90
|
+
<<~STRING
|
91
|
+
Greetings,
|
92
|
+
|
93
|
+
We have checked our systems and have not located any suppressions at this time for your email address (#{@email}). We would recommend checking your spam folder or contacting your email provider to help in locating any recent emails from us you may have received or requested.
|
94
|
+
|
95
|
+
Some common links you might need to get a new email are:
|
96
|
+
|
97
|
+
- Request a new confirmation email via https://gitlab.com/users/confirmation/new
|
98
|
+
- Request a new verification challenge by logging into GitLab.com directly and using the link in the prompt.
|
99
|
+
- Request a password reset on gitlab.com via https://gitlab.com/users/password/new
|
100
|
+
STRING
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.suppression_removed_note(bounce)
|
104
|
+
<<~STRING
|
105
|
+
Suppression found and removed in mg.gitlab.com:
|
106
|
+
|
107
|
+
- Email: #{bounce.address}
|
108
|
+
- Code: #{bounce.code}
|
109
|
+
- Error: #{bounce.error}
|
110
|
+
- Time: #{bounce.created_at}
|
111
|
+
STRING
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.suppression_removed_comment
|
115
|
+
<<~STRING
|
116
|
+
Greetings,
|
117
|
+
|
118
|
+
It looks like a suppression had been placed in our system on your email address (#{@email}) for gitlab.com emails, so no further emails from that system would have reached you.
|
119
|
+
|
120
|
+
We have cleared that suppression for you at this time.
|
121
|
+
|
122
|
+
Some common links you might need to get a new email are:
|
123
|
+
|
124
|
+
- Request a new confirmation email via https://gitlab.com/users/confirmation/new
|
125
|
+
- Request a new verification challenge by logging into GitLab.com directly and using the link in the prompt.
|
126
|
+
- Request a password reset on gitlab.com via https://gitlab.com/users/password/new
|
127
|
+
|
128
|
+
With the removal of the suppression, this ticket has been marked as solved.
|
129
|
+
|
130
|
+
If the suppression removal did not solve the problem and you are still not receiving emails from gitlab.com, please reply to this email to reopen the ticket and alert GitLab Support.
|
131
|
+
STRING
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Defines the module Readiness.
|
4
|
+
module Readiness
|
5
|
+
# Defines the module TicketProcessor
|
6
|
+
module TicketProcessor
|
7
|
+
##
|
8
|
+
# Defines the class LinkTagger within the module {Readiness::Zendesk}.
|
9
|
+
#
|
10
|
+
# @author Jason Colyer
|
11
|
+
# @since 1.0.44
|
12
|
+
class LinkTagger < Readiness::Client
|
13
|
+
##
|
14
|
+
# Process a Link Tagging request
|
15
|
+
#
|
16
|
+
# @author Jason Colyer
|
17
|
+
# @since 1.0.44
|
18
|
+
def self.process!(zendesk_client, gitlab_client, ticket_id)
|
19
|
+
@zendesk_client = zendesk_client
|
20
|
+
@gitlab_client = gitlab_client
|
21
|
+
@ticket_id = ticket_id
|
22
|
+
@user = Readiness::Zendesk::Users.find(@zendesk_client, ENV.fetch('COMMENT_AUTHOR'))
|
23
|
+
puts 'No such user, so no comment to review' if @user.is_a? Hash
|
24
|
+
exit 0 if @user.is_a? Hash
|
25
|
+
puts 'User is not an agent, so not proceeding' unless %w[admin agent].include? @user.role
|
26
|
+
exit 0 unless %w[admin agent].include? @user.role
|
27
|
+
@ticket = Readiness::Zendesk::Tickets.find(@zendesk_client, @ticket_id)
|
28
|
+
puts 'No ticket found, so no tags to add' if @ticket.is_a? Hash
|
29
|
+
exit 0 if @ticket.is_a? Hash
|
30
|
+
|
31
|
+
comments = Readiness::Zendesk::Tickets.comments(@zendesk_client, @ticket)
|
32
|
+
public_comments = comments.select { |c| c['public'] }
|
33
|
+
comment_to_check = public_comments.select { |c| c['author_id'] == @user.id }.last
|
34
|
+
tags_to_add = []
|
35
|
+
Nokogiri::HTML(comment_to_check['html_body']).css('a').each do |p|
|
36
|
+
link = p['href'].split('?').first.split('#').first
|
37
|
+
domain = link.split('/')[2]
|
38
|
+
if domain == 'gitlab.com'
|
39
|
+
if link =~ %r{/-/issues/[0-9]+}
|
40
|
+
slug = link.split("#{domain}/").last.split(%r{/-/issues/[0-9]+}).first
|
41
|
+
project = Readiness::GitLab::Projects.find(@gitlab_client, CGI.escape(slug))
|
42
|
+
unless project.is_a? Hash
|
43
|
+
iid = link.split('/').last
|
44
|
+
issue = Readiness::GitLab::Issues.find(@gitlab_client, project, iid)
|
45
|
+
unless issue.is_a? Hash
|
46
|
+
tags_to_add.push('gitlab_issue_link')
|
47
|
+
tags_to_add.push("#{slug.gsub('/', '_')}_issues_#{iid}")
|
48
|
+
tags_to_add.push("issue~#{slug.gsub('/', '~')}_#{iid}")
|
49
|
+
tags_to_add.push("issue_#{project.id}_#{iid}")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
elsif link =~ %r{/-/merge_requests/[0-9]+}
|
53
|
+
slug = link.split("#{domain}/").last.split(%r{/-/merge_requests/[0-9]+}).first
|
54
|
+
project = Readiness::GitLab::Projects.find(@gitlab_client, CGI.escape(slug))
|
55
|
+
unless project.is_a? Hash
|
56
|
+
iid = link.split('/').last
|
57
|
+
mr = Readiness::GitLab::MergeRequests.find(@gitlab_client, project, iid)
|
58
|
+
unless mr['message']
|
59
|
+
tags_to_add.push('gitlab_merge_request_link')
|
60
|
+
tags_to_add.push("#{slug.gsub('/', '_')}_merge_requests_#{iid}")
|
61
|
+
tags_to_add.push("mergerequest~#{slug.gsub('/', '~')}_#{iid}")
|
62
|
+
tags_to_add.push("mergerequest_#{project.id}_#{iid}")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
elsif domain == 'docs.gitlab.com'
|
67
|
+
tags_to_add.push('docs_link')
|
68
|
+
elsif domain == 'handbook.gitlab.com'
|
69
|
+
tags_to_add.push('hb_link')
|
70
|
+
elsif domain == 'support.gitlab.com'
|
71
|
+
if link =~ %r{articles}
|
72
|
+
tags_to_add.push('kb_link') unless link =~ %r{4911284066204}
|
73
|
+
end
|
74
|
+
elsif call_domains.include? domain
|
75
|
+
tags_to_add.push('agent_offered_call')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
if tags_to_add.uniq.count.zero?
|
79
|
+
puts 'No tags to add on this ticket'
|
80
|
+
exit 0
|
81
|
+
else
|
82
|
+
print "Adding #{tags_to_add.uniq.count} tag(s) to ticket..."
|
83
|
+
@ticket = Readiness::Zendesk::Tickets.find(@zendesk_client, @ticket_id)
|
84
|
+
new_ticket = Readiness::Zendesk::Tickets.new
|
85
|
+
new_ticket.id = @ticket.id
|
86
|
+
new_ticket.tags = @ticket.tags + tags_to_add.uniq
|
87
|
+
Readiness::Zendesk::Tickets.update!(@zendesk_client, new_ticket)
|
88
|
+
puts 'done'
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.call_domains
|
93
|
+
[
|
94
|
+
'calendly.com',
|
95
|
+
'gitlab.zoom.us',
|
96
|
+
'gitlabmtgs.webex.com',
|
97
|
+
'teams.microsoft.com'
|
98
|
+
]
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Defines the module Readiness.
|
4
|
+
module Readiness
|
5
|
+
# Defines the module TicketProcessor
|
6
|
+
module TicketProcessor
|
7
|
+
##
|
8
|
+
# Defines the class LockedAccount within the module {Readiness::Zendesk}.
|
9
|
+
#
|
10
|
+
# @author Jason Colyer
|
11
|
+
# @since 1.0.44
|
12
|
+
class LockedAccount < Readiness::Client
|
13
|
+
##
|
14
|
+
# Process a Locked Account request
|
15
|
+
#
|
16
|
+
# @author Jason Colyer
|
17
|
+
# @since 1.0.44
|
18
|
+
def self.process!(zendesk_client, ticket_id)
|
19
|
+
@zendesk_client = zendesk_client
|
20
|
+
@ticket_id = ticket_id
|
21
|
+
@ticket = Readiness::Zendesk::Tickets.find(@zendesk_client, @ticket_id)
|
22
|
+
puts 'No ticket found, so no org notes to add' if @ticket.is_a? Hash
|
23
|
+
exit 0 if @ticket.is_a? Hash
|
24
|
+
|
25
|
+
puts 'Ticket is closed, so no org notes to add' if @ticket.status == 'closed'
|
26
|
+
exit 0 if @ticket.status == 'closed'
|
27
|
+
|
28
|
+
new_ticket = Readiness::Zendesk::Tickets.new
|
29
|
+
new_ticket.id = @ticket.id
|
30
|
+
new_ticket.status = 'pending'
|
31
|
+
new_ticket.comment = { body: locked_account_comment }
|
32
|
+
new_ticket.custom_fields = [
|
33
|
+
{ id: 360020735259, value: 'stage-frt' }
|
34
|
+
]
|
35
|
+
Readiness::Zendesk::Tickets.update!(zendesk_client, new_ticket)
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.locked_account_comment
|
39
|
+
<<~STRING
|
40
|
+
Hi,
|
41
|
+
|
42
|
+
Thank you for contacting GitLab support.
|
43
|
+
|
44
|
+
The account may be locked if the system has registered too many login attempts during a short period of time. It will be locked for 30 minutes, after which it will be unlocked automatically.
|
45
|
+
|
46
|
+
On GitLab.com, we can also lock an account when there are 3 or more failed login attempts within 24 hours. Upon successful login, you may be redirected to a verification page and an email message with a 6-digit code is sent to your _primary_ email account. Please check your email (including the spam folder) for a message with a 6-digit code to unlock your account.
|
47
|
+
|
48
|
+
Please let us know if you have any further questions or are unable to receive any emails for your account.
|
49
|
+
STRING
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,223 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Defines the module Readiness.
|
4
|
+
module Readiness
|
5
|
+
# Defines the module TicketProcessor
|
6
|
+
module TicketProcessor
|
7
|
+
##
|
8
|
+
# Defines the class Namesquatting within the module {Readiness::Zendesk}.
|
9
|
+
#
|
10
|
+
# @author Jason Colyer
|
11
|
+
# @since 1.0.44
|
12
|
+
class Namesquatting < Readiness::Client
|
13
|
+
##
|
14
|
+
# Process a Blocked Account request
|
15
|
+
#
|
16
|
+
# @author Jason Colyer
|
17
|
+
# @since 1.0.44
|
18
|
+
def self.process!(zendesk_client, gitlab_admin_client, ticket_id)
|
19
|
+
@zendesk_client = zendesk_client
|
20
|
+
@gitlab_admin_client = gitlab_admin_client
|
21
|
+
@ticket_id = ticket_id
|
22
|
+
@ticket = Readiness::Zendesk::Tickets.find(@zendesk_client, @ticket_id)
|
23
|
+
puts 'No ticket found, so no org notes to add' if @ticket.is_a? Hash
|
24
|
+
exit 0 if @ticket.is_a? Hash
|
25
|
+
|
26
|
+
puts 'Ticket is closed, so no org notes to add' if @ticket.status == 'closed'
|
27
|
+
exit 0 if @ticket.status == 'closed'
|
28
|
+
|
29
|
+
return not_for_free_users unless paid_tags.any? { |t| @ticket.tags.include? t }
|
30
|
+
return invalid_namespace if Readiness::GitLab::Namespaces.exists?(@gitlab_admin_client, namespace_to_check)
|
31
|
+
return rejection_request if Readiness::GitLab::Namespaces.is_paid?(@gitlab_admin_client, namespace)
|
32
|
+
|
33
|
+
group_checks if namespace.kind == 'group'
|
34
|
+
user_checks if namespace.kind == 'user'
|
35
|
+
# check if free user ticket, if so reject
|
36
|
+
# check if valid namespace, if not reject
|
37
|
+
# check if namespace is paid, if so reject
|
38
|
+
# group checks
|
39
|
+
# immediate if zero projects and not created within 6 months
|
40
|
+
# immediate if no data and not created within 6 months
|
41
|
+
# reject if recent activity
|
42
|
+
# immediate_release if !(projects || data) && not recent owner signin
|
43
|
+
# contact_owner(owners)
|
44
|
+
# user checks
|
45
|
+
# immediate if unconfirmed and created within 90 days
|
46
|
+
# immediate if (no recent signing AND not only maintainer) AND projects have no data
|
47
|
+
# contact owner if (!recent_signin?(user) && !only_maintainer?(user)) && projects_have_data?(user)
|
48
|
+
# reject
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.group_checks
|
52
|
+
group = Readiness::GitLab::Groups.new
|
53
|
+
group.id = namespace.id
|
54
|
+
request = @gitlab_admin_client.connection.get "groups/#{namespace.id}"
|
55
|
+
group_data = Oj.load(request.body)
|
56
|
+
has_data = false
|
57
|
+
recent_activity = false
|
58
|
+
projects = Readiness::GitLab::Groups.projects(@gitlab_admin_client, group, ["archived=false", "include_subgroups=true"])
|
59
|
+
members = Readiness::GitLab::Groups.members(@gitlab_admin_client, group)
|
60
|
+
owners_list = members.select { |m| m['access_level'] == 50 }
|
61
|
+
owners = []
|
62
|
+
|
63
|
+
projects.each do |p|
|
64
|
+
has_data = true if p.empty_repo
|
65
|
+
recent_activity = true if (Date.today - 2.years) < Date.parse(p.last_activity_at)
|
66
|
+
end
|
67
|
+
created_recently = Date.parse(group_data['created_at']) <= (Date.today + 6.months)
|
68
|
+
return immediate_release if projects.count.zero? && !created_recently
|
69
|
+
return immediate_release if !has_data && !created_recently
|
70
|
+
return rejection_request if recent_activity
|
71
|
+
|
72
|
+
owners_list.each do |o|
|
73
|
+
search = Readiness::GitLab::Users.search_by_username(@gitlab_admin_client, i['username'])
|
74
|
+
owners.push(search.detect { |s| s.username.downcase == i['username'].downcase })
|
75
|
+
end
|
76
|
+
recent_owner_signin = false
|
77
|
+
owners.compact.each do |o|
|
78
|
+
recent_owner_signin = true if (Date.today - 2.years) < Date.parse(o.last_sign_in_at)
|
79
|
+
end
|
80
|
+
return immediate_release if (projects.count.zero? || !has_data) && !recent_owner_signin
|
81
|
+
|
82
|
+
contact_owner(owners)
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.user_checks
|
86
|
+
search = Readiness::GitLab::Users.search_by_username(@gitlab_admin_client, namespace_to_check)
|
87
|
+
user_namespace = search.detect { |s| s.username.downcase == namespace_to_check.downcase }
|
88
|
+
created_recently = (Date.today - 90.days) < Date.parse(user_namespace.created_at)
|
89
|
+
return immediate_release if user_namespace.confirmed_at.nil? && !created_recently
|
90
|
+
|
91
|
+
has_data = false
|
92
|
+
projects = Readiness::GitLab::Users.projects(@gitlab_admin_client, user_namespace, ["archived=false"])
|
93
|
+
projects.each do |p|
|
94
|
+
has_data = true if p.empty_repo
|
95
|
+
break if has_data
|
96
|
+
end
|
97
|
+
maintainer_check = Readiness::GitLab::Users.only_maintainer?(@gitlab_admin_client, user_namespace)
|
98
|
+
recent_signin = (Date.today - 90.days) < Date.parse(user_namespace.created_at)
|
99
|
+
return immediate_release if (!created_recently && !maintainer_check) && !has_data
|
100
|
+
return contact_owner([user_namespace]) if (!recent_signin && !maintainer_check) && has_data
|
101
|
+
|
102
|
+
rejection_request
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.paid_tags
|
106
|
+
%w[priority-prospect ultimater premium gold silver]
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.namespace
|
110
|
+
@namespace ||= Readiness::GitLab::Namespaces.find(@gitlab_admin_client, namespace_to_check)
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.namespace_to_check
|
114
|
+
@namespace_to_check ||= ENV.fetch('NAMESPACE')
|
115
|
+
end
|
116
|
+
|
117
|
+
def self.not_for_free_users
|
118
|
+
new_ticket = Readiness::Zendesk::Tickets.new
|
119
|
+
new_ticket.id = @ticket.id
|
120
|
+
new_ticket.status = 'solved'
|
121
|
+
new_ticket.comment = { body: not_for_free_users_comment, public: true }
|
122
|
+
new_ticket.custom_fields = [
|
123
|
+
{ id: 360020735259, value: 'stage-frt' }
|
124
|
+
]
|
125
|
+
Readiness::Zendesk::Tickets.update!(@zendesk_client, new_ticket)
|
126
|
+
end
|
127
|
+
|
128
|
+
def self.invalid_namespace
|
129
|
+
new_ticket = Readiness::Zendesk::Tickets.new
|
130
|
+
new_ticket.id = @ticket.id
|
131
|
+
new_ticket.status = 'solved'
|
132
|
+
new_ticket.comment = { body: invalid_namespace_comment, public: true }
|
133
|
+
new_ticket.custom_fields = [
|
134
|
+
{ id: 360020735259, value: 'stage-frt' }
|
135
|
+
]
|
136
|
+
Readiness::Zendesk::Tickets.update!(@zendesk_client, new_ticket)
|
137
|
+
end
|
138
|
+
|
139
|
+
def self.immediate_release
|
140
|
+
new_ticket = Readiness::Zendesk::Tickets.new
|
141
|
+
new_ticket.id = @ticket.id
|
142
|
+
new_ticket.comment = { body: immediate_release_comment, public: false }
|
143
|
+
new_ticket.custom_fields = [
|
144
|
+
{ id: 360020735259, value: 'stage-frt' }
|
145
|
+
]
|
146
|
+
Readiness::Zendesk::Tickets.update!(@zendesk_client, new_ticket)
|
147
|
+
end
|
148
|
+
|
149
|
+
def self.rejection_request
|
150
|
+
new_ticket = Readiness::Zendesk::Tickets.new
|
151
|
+
new_ticket.id = @ticket.id
|
152
|
+
new_ticket.status = 'solved'
|
153
|
+
new_ticket.comment = { body: rejection_request_comment, public: true }
|
154
|
+
new_ticket.custom_fields = [
|
155
|
+
{ id: 360020735259, value: 'stage-frt' }
|
156
|
+
]
|
157
|
+
Readiness::Zendesk::Tickets.update!(@zendesk_client, new_ticket)
|
158
|
+
end
|
159
|
+
|
160
|
+
def self.contact_owner(owners)
|
161
|
+
new_ticket = Readiness::Zendesk::Tickets.new
|
162
|
+
new_ticket.id = @ticket.id
|
163
|
+
new_ticket.comment = { body: contact_owner_comment(owners), public: true }
|
164
|
+
new_ticket.custom_fields = [
|
165
|
+
{ id: 360020735259, value: 'stage-frt' }
|
166
|
+
]
|
167
|
+
Readiness::Zendesk::Tickets.update!(@zendesk_client, new_ticket)
|
168
|
+
end
|
169
|
+
|
170
|
+
def self.not_for_free_users_comment
|
171
|
+
<<~STRING
|
172
|
+
Hello,
|
173
|
+
|
174
|
+
Thank you for reaching out.
|
175
|
+
|
176
|
+
Please note that According to our [Name Squatting Policy](https://about.gitlab.com/support/gitlab-com-policies/#name-squatting-policy), namespaces may be released when they meet the appropriate criteria, and requested **by a member of paid namespace**.
|
177
|
+
|
178
|
+
Unfortunately your account doesn't appear to be part of a paid namespace so it isn't eligible for the namesquatting policy. If you believe we made a mistake and you are a part of the paid namespace please let us know and we will revisit this request.
|
179
|
+
|
180
|
+
I'll mark this ticket as solved, please reach out if you have any further questions.
|
181
|
+
STRING
|
182
|
+
end
|
183
|
+
|
184
|
+
def self.invalid_namespace_comment
|
185
|
+
<<~STRING
|
186
|
+
Hello,
|
187
|
+
|
188
|
+
We were unable to locate the namespace `#{namespace_to_check}` on gitlab.com at this time. As such, this should mean you are able to utilize it for your setup.
|
189
|
+
|
190
|
+
I'll mark this ticket as solved, please reach out if you have any further questions.
|
191
|
+
STRING
|
192
|
+
end
|
193
|
+
|
194
|
+
def self.immediate_release_comment
|
195
|
+
<<~STRING
|
196
|
+
The namespace checks for #{namespace_to_check} have determined it is available for immediate release.
|
197
|
+
STRING
|
198
|
+
end
|
199
|
+
|
200
|
+
def self.rejection_request_comment
|
201
|
+
<<~STRING
|
202
|
+
Hello,
|
203
|
+
|
204
|
+
The namespace requested `#{namespace_to_check}` is **not eligible** for release in accordance with our [Name Squatting Policy](https://about.gitlab.com/support/gitlab-com-policies/#name-squatting-policy) and we are unable to process your request. As per our [Subscription Agreement](https://about.gitlab.com/handbook/legal/subscription-agreement/#5-restrictions-and-responsibilities) point 5.8, `Account names are administered by GitLab on a "first come, first served" basis`.
|
205
|
+
|
206
|
+
Please note often activity cannot be seen for private namespaces, so activity on a profile is not a true indicator of whether a namespace is active. Profiles can also be made private which also hides activity from public view.
|
207
|
+
|
208
|
+
I'll mark this ticket as solved, please reach out if you have any further questions.
|
209
|
+
STRING
|
210
|
+
end
|
211
|
+
|
212
|
+
def self.contact_owner_comment(owners)
|
213
|
+
<<~STRING
|
214
|
+
The namespace checks for #{namespace_to_check} have determined it might be eligible for release after contacting owners.
|
215
|
+
|
216
|
+
The list of owner emails are:
|
217
|
+
|
218
|
+
#{owners.map { |o| "- #{o.email}" }.join("\n")}
|
219
|
+
STRING
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|