gitlab_support_readiness 1.0.123 → 1.0.125

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '085df90efaf00015b0808f25947e245de37bf847286dab6e152db454cb481b43'
4
- data.tar.gz: 6a9900d29dfb44010aec828bc2cc5aa538d751ce34ffb85a204a8d5a41d794c9
3
+ metadata.gz: 77742079ee62db6c4f2ed4dce4642ea2bf2fa06e3fd473d9cbe99e81e0f3bfae
4
+ data.tar.gz: 5756f05d4e08901351b13bb437c8681cc4c88267f653c28ff57d509c3cc468ac
5
5
  SHA512:
6
- metadata.gz: 237f7f7152ef2d7a4bb349106e5d71bf8b8c2596d63358e32e4bbc6a3d4d097eafecea7b724840442f7901256e2908a42814c94d319512d73dfd7d85622d6cdc
7
- data.tar.gz: e2de7be780418546bbae9cb105be7347b8ea5bfa381015819076e5105a38e954d18ff6dc8be6d2dfd758794a26321effc3719ab20aab7322df07e0514cd3d914
6
+ metadata.gz: 2929642f4896b0c56d0edfc3c48464a0aa0da419cd6fd94cedd6bb64f8bcca8e2672fa41e61d8c37e0b700e9e91cd025474394508929fc1e09ff13a9f681df75
7
+ data.tar.gz: cdafbe5d734f4ad9e5eee5fe82593dfc46041884f3bf41665461652c635185ace3ee2346fb0065d6d4d0cee292711aee7db8551c31d330100bedd7ccd9debe96
@@ -0,0 +1,275 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Defines the module Readiness.
4
+ module Readiness
5
+ # Defines the module GitLab
6
+ module GitLab
7
+ ##
8
+ # Defines the class ProjectWebhooks within the module {Readiness::GitLab}.
9
+ #
10
+ # @author Jason Colyer
11
+ # @since 1.0.124
12
+ # @todo resend_event! https://docs.gitlab.com/ee/api/project_webhooks.html#resend-a-project-webhook-event
13
+ # @todo trigger! https://docs.gitlab.com/ee/api/project_webhooks.html#trigger-a-test-project-webhook
14
+ # @todo set_custom_header! https://docs.gitlab.com/ee/api/project_webhooks.html#set-a-custom-header
15
+ # @todo delete_custom_header! https://docs.gitlab.com/ee/api/project_webhooks.html#delete-a-custom-header
16
+ # @todo set_url_variable! https://docs.gitlab.com/ee/api/project_webhooks.html#set-a-url-variable
17
+ # @todo delete_url_variable! https://docs.gitlab.com/ee/api/project_webhooks.html#delete-a-url-variable
18
+ class ProjectWebhooks < Readiness::Client
19
+ attr_accessor :alert_status, :branch_filter_strategy, :confidential_issues_events, :confidential_note_events, :created_at, :custom_headers, :custom_webhook_template, :deployment_events, :description, :disabled_until, :enable_ssl_verification, :feature_flag_events, :id, :issues_events, :job_events, :merge_requests_events, :name, :note_events, :pipeline_events, :project_id, :push_events, :push_events_branch_filter, :releases_events, :repository_update_events, :resource_access_token_events, :tag_push_events, :token, :url, :url_variables, :wiki_page_events
20
+
21
+ ##
22
+ # Creates a new {Readiness::GitLab::ProjectWebhooks} instance
23
+ #
24
+ # @author Jason Colyer
25
+ # @since 1.0.124
26
+ # @param object [Object] An instance of {Readiness::GitLab::ProjectWebhooks}
27
+ # @example
28
+ # require 'support_readiness'
29
+ # Readiness::GitLab::ProjectWebhooks.new
30
+ def initialize(object = {})
31
+ @alert_status = object['alert_status']
32
+ @branch_filter_strategy = object['branch_filter_strategy']
33
+ @confidential_issues_events = object['confidential_issues_events']
34
+ @confidential_note_events = object['confidential_note_events']
35
+ @created_at = object['created_at']
36
+ @custom_headers = object['custom_headers']
37
+ @custom_webhook_template = object['custom_webhook_template']
38
+ @deployment_events = object['deployment_events']
39
+ @description = object['description']
40
+ @disabled_until = object['disabled_until']
41
+ @enable_ssl_verification = object['enable_ssl_verification']
42
+ @feature_flag_events = object['feature_flag_events']
43
+ @id = object['id']
44
+ @issues_events = object['issues_events']
45
+ @job_events = object['job_events']
46
+ @merge_requests_events = object['merge_requests_events']
47
+ @name = object['name']
48
+ @note_events = object['note_events']
49
+ @pipeline_events = object['pipeline_events']
50
+ @project_id = object['project_id']
51
+ @push_events = object['push_events']
52
+ @push_events_branch_filter = object['push_events_branch_filter']
53
+ @releases_events = object['releases_events']
54
+ @repository_update_events = object['repository_update_events']
55
+ @resource_access_token_events = object['resource_access_token_events']
56
+ @tag_push_events = object['tag_push_events']
57
+ @token = object['token']
58
+ @url = object['url']
59
+ @url_variables = object['url_variables']
60
+ @wiki_page_events = object['wiki_page_events']
61
+ end
62
+
63
+ ##
64
+ # Lists webhooks for a project.
65
+ #
66
+ # @author Jason Colyer
67
+ # @since 1.0.124
68
+ # @param client [Object] An instance of {Readiness::GitLab::Client}
69
+ # @param project [Object] An instance of {Readiness::GitLab::Projects}
70
+ # @return [Array]
71
+ # @see https://docs.gitlab.com/ee/api/project_webhooks.html#list-webhooks-for-a-project GitLab API > Projects > Webhooks > List webhooks for a project
72
+ # @example
73
+ # require 'support_readiness'
74
+ # config = Readiness::GitLab::Configuration.new
75
+ # config.token = 'test123abc'
76
+ # client = Readiness::GitLab::Client.new(config)
77
+ # project = Readiness::GitLab::Projects.find!(client, 1083469)
78
+ # hooks = Readiness::GitLab::ProjectWebhooks.list(client, project)
79
+ # pp hooks.first.url
80
+ # # => "Hook name"
81
+ def self.list(client, project)
82
+ response = client.connection.get "projects/#{project.id}/hooks"
83
+ handle_request_error(0, 'GitLab', response.status) unless response.status == 200
84
+ body = Oj.load(response.body)
85
+ body.map { |p| ProjectWebhooks.new(p) }
86
+ end
87
+
88
+ ##
89
+ # Locates a project webhook within GitLab. This will not exit on error (except Authentication errors)
90
+ #
91
+ # @author Jason Colyer
92
+ # @since 1.0.124
93
+ # @param client [Object] An instance of {Readiness::GitLab::Client}
94
+ # @param project [Object] An instance of {Readiness::GitLab::Projects}
95
+ # @param hook_id [Integer] The project webhook ID to find
96
+ # @return [Hash]
97
+ # @see https://docs.gitlab.com/ee/api/project_webhooks.html#get-a-project-webhook GitLab API > Projects > Webhooks > Get a project webhook
98
+ # @example
99
+ # require 'support_readiness'
100
+ # config = Readiness::GitLab::Configuration.new
101
+ # config.token = 'test123abc'
102
+ # client = Readiness::GitLab::Client.new(config)
103
+ # project = Readiness::GitLab::Projects.find!(client, 1083469)
104
+ # hook = Readiness::GitLab::Issues.find(client, project, 1)
105
+ # pp hook.name
106
+ # # => "Hook name"
107
+ def self.find(client, project, hook_id)
108
+ response = client.connection.get ""
109
+ handle_request_error(0, 'GitLab', response.status, { action: 'get', id: hook_id }) unless response.status == 200
110
+ return ProjectWebhooks.new(Oj.load(response.body)) if response.status == 200
111
+
112
+ Oj.load(response.body)
113
+ end
114
+
115
+ ##
116
+ # Locates a project webhook within GitLab. This will exit on error
117
+ #
118
+ # @param client [Object] An instance of {Readiness::GitLab::Client}
119
+ # @param project [Object] An instance of {Readiness::GitLab::Projects}
120
+ # @param hook_id [Integer] The project webhook ID to find
121
+ # @return [Hash]
122
+ # @see https://docs.gitlab.com/ee/api/project_webhooks.html#get-a-project-webhook GitLab API > Projects > Webhooks > Get a project webhook
123
+ # @example
124
+ # require 'support_readiness'
125
+ # config = Readiness::GitLab::Configuration.new
126
+ # config.token = 'test123abc'
127
+ # client = Readiness::GitLab::Client.new(config)
128
+ # project = Readiness::GitLab::Projects.find!(client, 1083469)
129
+ # hook = Readiness::GitLab::Issues.find!(client, project, 1)
130
+ # pp hook.name
131
+ # # => "Hook name"
132
+ def self.find!(client, project, hook_id)
133
+ response = client.connection.get ""
134
+ handle_request_error(1, 'GitLab', response.status, { action: 'Find webhook', id: "#{project.id}##{hook_id}" }) unless response.status == 200
135
+ ProjectWebhooks.new(Oj.load(response.body))
136
+ end
137
+
138
+ ##
139
+ # Lists project webhook events. Does not stop until it ends or the page limit is hit.
140
+ # This method can take a long time to run depending on the parameters used.
141
+ #
142
+ # @author Jason Colyer
143
+ # @since 1.0.124
144
+ # @param client [Object] An instance of {Readiness::GitLab::Client}
145
+ # @param project [Object] An instance of {Readiness::GitLab::Projects}
146
+ # @param status [Various] Response status code of the events (see docs for more info). Omit to get all events
147
+ # @return [Array]
148
+ # @see https://docs.gitlab.com/ee/api/project_webhooks.html#get-a-list-of-project-webhook-events GitLab API > Projects > Webhooks > Get a list of project webhook events
149
+ # @example
150
+ # require 'support_readiness'
151
+ # config = Readiness::GitLab::Configuration.new
152
+ # config.token = 'test123abc'
153
+ # client = Readiness::GitLab::Client.new(config)
154
+ # project = Readiness::GitLab::Projects.find!(client, 1083469)
155
+ # hooks = Readiness::GitLab::ProjectWebhooks.find!(client, project, 1)
156
+ # events = Readiness::GitLab::ProjectWebhooks.events(client, hook)
157
+ # pp events.first['trigger']
158
+ # # => "push_hooks"
159
+ # @example
160
+ # require 'support_readiness'
161
+ # config = Readiness::GitLab::Configuration.new
162
+ # config.token = 'test123abc'
163
+ # client = Readiness::GitLab::Client.new(config)
164
+ # project = Readiness::GitLab::Projects.find!(client, 1083469)
165
+ # hooks = Readiness::GitLab::ProjectWebhooks.find!(client, project, 1)
166
+ # events = Readiness::GitLab::ProjectWebhooks.events(client, hook, 200)
167
+ # pp events.first['trigger']
168
+ # # => "push_hooks"
169
+ def self.events(client, hook, status = false)
170
+ root_url = if status
171
+ "projects/#{hook.project_id}/hooks/#{hood.id}/events?status=#{status}"
172
+ else
173
+ "projects/#{hook.project_id}/hooks/#{hood.id}/events?"
174
+ end
175
+ array = []
176
+ page = 1
177
+ loop do
178
+ response = client.connection.get "#{root_url}&per_page=100&page=#{page}"
179
+ handle_request_error(0, 'GitLab', response.status) unless response.status == 200
180
+ body = Oj.load(response.body)
181
+ array += body
182
+ break if body.count < 100
183
+
184
+ page += 1
185
+ end
186
+ array
187
+ end
188
+
189
+ ##
190
+ # Creates a project webhook within GitLab. This will exit on error
191
+ #
192
+ # @author Jason Colyer
193
+ # @since 1.0.124
194
+ # @param client [Object] An instance of {Readiness::GitLab::Client}
195
+ # @param hook [Object] An instance of {Readiness::GitLab::ProjectWebhooks}
196
+ # @return [Object] An instance of {Readiness::GitLab::ProjectWebhooks}
197
+ # @see https://docs.gitlab.com/ee/api/project_webhooks.html#add-a-webhook-to-a-project > Project > Webhooks > Add a webhook to a project
198
+ # @example
199
+ # require 'support_readiness'
200
+ # config = Readiness::GitLab::Configuration.new
201
+ # config.token = 'test123abc'
202
+ # client = Readiness::GitLab::Client.new(config)
203
+ # hook = Readiness::GitLab::ProjectWebhooks.new
204
+ # hook.url = 'http://example.com/hook'
205
+ # hook.name = 'Hook name'
206
+ # hook.description = 'Hook description'
207
+ # hook.project_id = 1083469
208
+ # hook.push_events = true
209
+ # hook.custom_webhook_template = '{ "event": "{{object_kind}}" }'
210
+ # hook.custom_headers = [
211
+ # 'Authorization'
212
+ # ]
213
+ # new_hook = Readiness::GitLab::ProjectWebhooks.create!(client, hook)
214
+ # pp new_hook.id
215
+ # # => 1
216
+ def self.create!(client, hook)
217
+ response = client.connection.post "projects/#{hook.project_id}/hooks", to_clean_json(hook)
218
+ handle_request_error(1, 'GitLab', response.status, { action: 'Create webhook', id: hook.project_id }) unless response.status == 200
219
+ ProjectWebhooks.new(Oj.load(response.body))
220
+ end
221
+
222
+ ##
223
+ # Updates a project webhook within GitLab. This will exit on error
224
+ #
225
+ # @author Jason Colyer
226
+ # @since 1.0.124
227
+ # @param client [Object] An instance of {Readiness::GitLab::Client}
228
+ # @param hook [Object] An instance of {Readiness::GitLab::ProjectWebhooks}
229
+ # @return [Object] An instance of {Readiness::GitLab::ProjectWebhooks}
230
+ # @see https://docs.gitlab.com/ee/api/project_webhooks.html#edit-a-project-webhook > Project > Webhooks > Edit a project webhook
231
+ # @example
232
+ # require 'support_readiness'
233
+ # config = Readiness::GitLab::Configuration.new
234
+ # config.token = 'test123abc'
235
+ # client = Readiness::GitLab::Client.new(config)
236
+ # project = Readiness::GitLab::Projects.find!(client, 1083469)
237
+ # hook = Readiness::GitLab::ProjectWebhooks.find(client, project, 1)
238
+ # hook.url = 'http://example.com/hook2'
239
+ # hook.name = 'Hook name v2'
240
+ # update = Readiness::GitLab::ProjectWebhooks.update!(client, hook)
241
+ # pp update.name
242
+ # # => "Hook name v2"
243
+ def self.update!(client, hook)
244
+ response = client.connection.put "project/#{hook.project_id}/hooks/#{hook.id}", to_clean_json(hook)
245
+ handle_request_error(1, 'GitLab', response.status, { action: 'Update webhook', id: "#{hook.project_id}##{hook.id}" }) unless response.status == 200
246
+ ProjectWebhooks.new(Oj.load(response.body))
247
+ end
248
+
249
+ ##
250
+ # Deletes a project webhook within GitLab. This will exit on error
251
+ #
252
+ # @author Jason Colyer
253
+ # @since 1.0.124
254
+ # @param client [Object] An instance of {Readiness::GitLab::Client}
255
+ # @param hook [Object] An instance of {Readiness::GitLab::ProjectWebhooks}
256
+ # @return [Boolean]
257
+ # @see https://docs.gitlab.com/ee/api/project_webhooks.html#delete-project-webhook > Project > Webhooks > Delete project webhook
258
+ # @example
259
+ # require 'support_readiness'
260
+ # config = Readiness::GitLab::Configuration.new
261
+ # config.token = 'test123abc'
262
+ # client = Readiness::GitLab::Client.new(config)
263
+ # project = Readiness::GitLab::Projects.find!(client, 1083469)
264
+ # hook = Readiness::GitLab::ProjectWebhooks.find(client, project, 1)
265
+ # delete = Readiness::GitLab::ProjectWebhooks.delete!(client, hook)
266
+ # pp delete
267
+ # # => true
268
+ def self.delete!(client, hook)
269
+ response = client.connection.delete "projects/#{hook.project_id}/hooks/#{hook.id}"
270
+ handle_request_error(1, 'GitLab', response.status, { action: 'Delete webhook', id: "#{hook.project_id}##{hook.id}" }) unless response.status == 2204
271
+ true
272
+ end
273
+ end
274
+ end
275
+ end
@@ -11,7 +11,7 @@ module Readiness
11
11
  # @since 1.0.0
12
12
  # @todo Anything listed on https://docs.gitlab.com/ee/api/projects.html not currently here
13
13
  class Projects < Readiness::Client
14
- attr_accessor :allow_merge_on_skipped_pipeline, :allow_pipeline_trigger_approve_deployment, :analytics_access_level, :approvals_before_merge, :archived, :auto_cancel_pending_pipelines, :autoclose_referenced_issues, :auto_devops_deploy_strategy, :auto_devops_enabled, :avatar_url, :build_git_strategy, :builds_access_level, :build_timeout, :can_create_merge_request_in, :ci_allow_fork_pipelines_to_run_in_parent_project, :ci_config_path, :ci_default_git_depth, :ci_forward_deployment_enabled, :ci_forward_deployment_rollback_allowed, :ci_id_token_sub_claim_components, :ci_job_token_scope_enabled, :ci_pipeline_variables_minimum_override_role, :ci_push_repository_for_job_token_allowed, :ci_restrict_pipeline_cancellation_role, :ci_separated_caches, :compliance_frameworks, :container_registry_access_level, :container_registry_enabled, :container_registry_image_prefix, :created_at, :creator_id, :custom_attributes, :default_branch, :description, :description_html, :emails_disabled, :emails_enabled, :empty_repo, :enforce_auth_checks_on_uploads, :environments_access_level, :external_authorization_classification_label, :feature_flags_access_level, :forked_from_project, :forking_access_level, :forks_count, :group_runners_enabled, :http_url_to_repo, :id, :import_error, :import_status, :import_type, :import_url, :infrastructure_access_level, :issue_branch_template, :issues_access_level, :issues_enabled, :issues_template, :jobs_enabled, :keep_latest_artifact, :last_activity_at, :lfs_enabled, :license, :license_url, :_links, :marked_for_deletion_at, :marked_for_deletion_on, :merge_commit_template, :merge_method, :merge_pipelines_enabled, :merge_requests_access_level, :merge_requests_enabled, :merge_requests_template, :merge_trains_enabled, :merge_trains_skip_train_allowed, :mirror, :model_experiments_access_level, :model_registry_access_level, :monitor_access_level, :mr_default_target_self, :name, :namespace, :name_with_namespace, :only_allow_merge_if_all_discussions_are_resolved, :only_allow_merge_if_all_status_checks_passed, :only_allow_merge_if_pipeline_succeeds, :open_issues_count, :packages_enabled, :pages_access_level, :path, :path_with_namespace, :permissions, :pre_receive_secret_detection_enabled, :prevent_merge_without_jira_issue, :printing_merge_request_link_enabled, :public_jobs, :readme_url, :releases_access_level, :remove_source_branch_after_merge, :repository_access_level, :repository_object_format, :repository_storage, :request_access_enabled, :requirements_access_level, :requirements_enabled, :resolve_outdated_diff_discussions, :restrict_user_defined_variables, :runners_token, :runner_token_expiration_interval, :security_and_compliance_access_level, :security_and_compliance_enabled, :service_desk_address, :service_desk_enabled, :shared_runners_enabled, :shared_with_groups, :snippets_access_level, :snippets_enabled, :squash_commit_template, :squash_option, :ssh_url_to_repo, :star_count, :statistics, :suggestion_commit_message, :tag_list, :topics, :updated_at, :visibility, :warn_about_potentially_unwanted_characters, :web_url, :wiki_access_level, :wiki_enabled
14
+ attr_accessor :allow_merge_on_skipped_pipeline, :allow_pipeline_trigger_approve_deployment, :analytics_access_level, :approvals_before_merge, :archived, :auto_cancel_pending_pipelines, :autoclose_referenced_issues, :auto_devops_deploy_strategy, :auto_devops_enabled, :avatar_url, :build_git_strategy, :builds_access_level, :build_timeout, :can_create_merge_request_in, :ci_allow_fork_pipelines_to_run_in_parent_project, :ci_config_path, :ci_default_git_depth, :ci_forward_deployment_enabled, :ci_forward_deployment_rollback_allowed, :ci_id_token_sub_claim_components, :ci_job_token_scope_enabled, :ci_pipeline_variables_minimum_override_role, :ci_push_repository_for_job_token_allowed, :ci_restrict_pipeline_cancellation_role, :ci_separated_caches, :compliance_frameworks, :container_expiration_policy, :container_registry_access_level, :container_registry_enabled, :container_registry_image_prefix, :created_at, :creator_id, :custom_attributes, :default_branch, :description, :description_html, :emails_disabled, :emails_enabled, :empty_repo, :enforce_auth_checks_on_uploads, :environments_access_level, :external_authorization_classification_label, :feature_flags_access_level, :forked_from_project, :forking_access_level, :forks_count, :group_runners_enabled, :http_url_to_repo, :id, :import_error, :import_status, :import_type, :import_url, :infrastructure_access_level, :issue_branch_template, :issues_access_level, :issues_enabled, :issues_template, :jobs_enabled, :keep_latest_artifact, :last_activity_at, :lfs_enabled, :license, :license_url, :_links, :marked_for_deletion_at, :marked_for_deletion_on, :merge_commit_template, :merge_method, :merge_pipelines_enabled, :merge_requests_access_level, :merge_requests_enabled, :merge_requests_template, :merge_trains_enabled, :merge_trains_skip_train_allowed, :mirror, :model_experiments_access_level, :model_registry_access_level, :monitor_access_level, :mr_default_target_self, :name, :namespace, :namespace_id, :name_with_namespace, :only_allow_merge_if_all_discussions_are_resolved, :only_allow_merge_if_all_status_checks_passed, :only_allow_merge_if_pipeline_succeeds, :open_issues_count, :packages_enabled, :pages_access_level, :path, :path_with_namespace, :permissions, :pre_receive_secret_detection_enabled, :prevent_merge_without_jira_issue, :printing_merge_request_link_enabled, :public_jobs, :readme_url, :releases_access_level, :remove_source_branch_after_merge, :repository_access_level, :repository_object_format, :repository_storage, :request_access_enabled, :requirements_access_level, :requirements_enabled, :resolve_outdated_diff_discussions, :restrict_user_defined_variables, :runners_token, :runner_token_expiration_interval, :security_and_compliance_access_level, :security_and_compliance_enabled, :service_desk_address, :service_desk_enabled, :shared_runners_enabled, :shared_with_groups, :snippets_access_level, :snippets_enabled, :squash_commit_template, :squash_option, :ssh_url_to_repo, :star_count, :statistics, :suggestion_commit_message, :tag_list, :topics, :updated_at, :visibility, :warn_about_potentially_unwanted_characters, :web_url, :wiki_access_level, :wiki_enabled
15
15
 
16
16
  ##
17
17
  # Creates a new {Readiness::GitLab::Projects} instance
@@ -49,6 +49,7 @@ module Readiness
49
49
  @ci_restrict_pipeline_cancellation_role = object['ci_restrict_pipeline_cancellation_role']
50
50
  @ci_separated_caches = object['ci_separated_caches']
51
51
  @compliance_frameworks = object['compliance_frameworks']
52
+ @container_expiration_policy = object['container_expiration_policy']
52
53
  @container_registry_access_level = object['container_registry_access_level']
53
54
  @container_registry_enabled = object['container_registry_enabled']
54
55
  @container_registry_image_prefix = object['container_registry_image_prefix']
@@ -103,6 +104,7 @@ module Readiness
103
104
  @monitor_access_level = object['monitor_access_level']
104
105
  @mr_default_target_self = object['mr_default_target_self']
105
106
  @name = object['name']
107
+ @namespace_id = object['namespace_id']
106
108
  @namespace = object['namespace']
107
109
  @name_with_namespace = object['name_with_namespace']
108
110
  @only_allow_merge_if_all_discussions_are_resolved = object['only_allow_merge_if_all_discussions_are_resolved']
@@ -279,6 +281,32 @@ module Readiness
279
281
  array
280
282
  end
281
283
 
284
+ ##
285
+ # Creates a project within GitLab. This will exit on error
286
+ #
287
+ # @author Jason Colyer
288
+ # @since 1.0.124
289
+ # @param client [Object] An instance of {Readiness::GitLab::Client}
290
+ # @param project [Object] An instance of {Readiness::GitLab::Projects}
291
+ # @return [Object] An instance of {Readiness::GitLab::Projects}
292
+ # @see https://docs.gitlab.com/ee/api/projects.html#create-a-project GitLab API > Projects > Create a project
293
+ # @example
294
+ # require 'support_readiness'
295
+ # config = Readiness::GitLab::Configuration.new
296
+ # config.token = 'test123abc'
297
+ # client = Readiness::GitLab::Client.new(config)
298
+ # project = Readiness::GitLab::Projects.new
299
+ # project.name = 'Test project'
300
+ # project.path = 'jason-test-project
301
+ # new_project = Readiness::GitLab::Projects.create!(client, project)
302
+ # puts new_project.web_url
303
+ # # => "https://gitlab.com/jason/jason-test-project"
304
+ def self.create!(client, project)
305
+ response = client.connection.post 'projects', to_clean_json(project)
306
+ handle_request_error(1, 'GitLab', response.status, { action: 'Create project', id: '' }) unless response.status == 200
307
+ Projects.new(Oj.load(response.body))
308
+ end
309
+
282
310
  ##
283
311
  # Lists all access tokens for a project
284
312
  #
@@ -595,6 +623,70 @@ module Readiness
595
623
  def self.jobs(client, project, limit = 0, filters = [])
596
624
  Jobs.list_project(client, project, limit, filters)
597
625
  end
626
+
627
+ ##
628
+ # Lists all project webhooks. This is a wrapper of {ProjectWebhooks#list}
629
+ #
630
+ # @author Jason Colyer
631
+ # @since 1.0.124
632
+ # @param client [Object] An instance of {Readiness::GitLab::Client}
633
+ # @param project [Object] An instance of {Readiness::GitLab::Projects}
634
+ # @return [Array]
635
+ # @see https://docs.gitlab.com/ee/api/project_webhooks.html#list-webhooks-for-a-project GitLab API > Projects > Webhooks > List webhooks for a project
636
+ # @example
637
+ # require 'support_readiness'
638
+ # config = Readiness::GitLab::Configuration.new
639
+ # config.token = 'test123abc'
640
+ # client = Readiness::GitLab::Client.new(config)
641
+ # project = Readiness::GitLab::Projects.find!(client, 1083469)
642
+ # hooks = Readiness::GitLab::Projects.webhooks(client, project)
643
+ # puts hooks.count
644
+ # # => 2
645
+ def self.webhooks(client, project)
646
+ ProjectWebhooks.list(client, project)
647
+ end
648
+
649
+ ##
650
+ # Create a membership invitation for a project. This will exit on error
651
+ #
652
+ # @author Jason Colyer
653
+ # @since 1.0.124
654
+ # @param client [Object] An instance of {Readiness::GitLab::Client}
655
+ # @param project [Object] An instance of {Readiness::GitLab::Projects}
656
+ # @param data [Hash] The invite information
657
+ # @return [Array]
658
+ # @see https://docs.gitlab.com/ee/api/invitations.html#add-a-member-to-a-group-or-project GitLab API > Invitations > Add a member to a group or project
659
+ # @example
660
+ # require 'support_readiness'
661
+ # config = Readiness::GitLab::Configuration.new
662
+ # config.token = 'test123abc'
663
+ # client = Readiness::GitLab::Client.new(config)
664
+ # project = Readiness::GitLab::Projects.find!(client, 1083469)
665
+ # data = {
666
+ # email: 'bob@example.com',
667
+ # access_level: 50
668
+ # }
669
+ # invite = Readiness::GitLab::Projects.create_invitation!(client, project, data)
670
+ # pp invite
671
+ # # => {"status"=>"success"}
672
+ # @example
673
+ # require 'support_readiness'
674
+ # config = Readiness::GitLab::Configuration.new
675
+ # config.token = 'test123abc'
676
+ # client = Readiness::GitLab::Client.new(config)
677
+ # project = Readiness::GitLab::Projects.find!(client, 1083469)
678
+ # data = {
679
+ # user_id: 123456,
680
+ # access_level: 40
681
+ # }
682
+ # invite = Readiness::GitLab::Projects.create_invitation!(client, project, data)
683
+ # pp invite
684
+ # # => {"status"=>"success"}
685
+ def self.create_invitation!(client, project, data)
686
+ response = client.connection.post "projects/#{project.id}/invitations", data.to_json
687
+ handle_request_error(1, 'GitLab', response.status, { action: 'Invite people', id: project.id }) unless response.status == 200
688
+ Oj.load(response.body)
689
+ end
598
690
  end
599
691
  end
600
692
  end
@@ -17,6 +17,7 @@ module Readiness
17
17
  require "#{__dir__}/gitlab/merge_requests"
18
18
  require "#{__dir__}/gitlab/namespaces"
19
19
  require "#{__dir__}/gitlab/pipelines"
20
+ require "#{__dir__}/gitlab/project_webhooks"
20
21
  require "#{__dir__}/gitlab/projects"
21
22
  require "#{__dir__}/gitlab/repositories"
22
23
  require "#{__dir__}/gitlab/users"
@@ -0,0 +1,282 @@
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 CMPCreation within the module {Readiness::Zendesk}.
9
+ #
10
+ # @author Jason Colyer
11
+ # @since 1.0.124
12
+ class CMPCreation < Readiness::Client
13
+ ##
14
+ # Process a CMP Creation request
15
+ #
16
+ # @author Jason Colyer
17
+ # @since 1.0.124
18
+ def self.process!(zendesk_client, gitlab_client, email_list)
19
+ @zendesk_client = zendesk_client
20
+ @gitlab_client = gitlab_client
21
+ @email_list = email_list
22
+ @project = create_project
23
+ create_readme_file
24
+ create_webhook
25
+ populate_contacts_file
26
+ send_invitations
27
+ update_organization
28
+ update_ticket
29
+ end
30
+
31
+ ##
32
+ # Fetches the ticket
33
+ #
34
+ # @author Jason Colyer
35
+ # @since 1.0.124
36
+ def self.ticket
37
+ @ticket ||= Readiness::Zendesk::Tickets.find!(@zendesk_client, ENV.fetch('TICKET_ID'))
38
+ end
39
+
40
+ ##
41
+ # Fetches the organization
42
+ #
43
+ # @author Jason Colyer
44
+ # @since 1.0.124
45
+ def self.organization
46
+ @organization ||= Readiness::Zendesk::Organizations.find!(@zendesk_client, ticket.organization_id)
47
+ end
48
+
49
+ ##
50
+ # Fetches the organization users
51
+ #
52
+ # @author Jason Colyer
53
+ # @since 1.0.124
54
+ def self.organization_users
55
+ @organization_users ||= Readiness::Zendesk::Organizations.users(@zendesk_client, organization)
56
+ end
57
+
58
+ ##
59
+ # Creates the actual CMP project
60
+ #
61
+ # @author Jason Colyer
62
+ # @since 1.0.124
63
+ def self.create_project
64
+ new_project = Readiness::GitLab::Projects.new
65
+ new_project.name = "Organization #{organization.id}"
66
+ new_project.path = "organization-#{organization.id}"
67
+ new_project.namespace_id = ENV.fetch('GROUP_ID')
68
+ new_project.analytics_access_level = 'disabled'
69
+ new_project.approvals_before_merge = 0
70
+ new_project.auto_cancel_pending_pipelines = 'enabled'
71
+ new_project.auto_devops_deploy_strategy = 'continuous'
72
+ new_project.auto_devops_enabled = false
73
+ new_project.autoclose_referenced_issues = true
74
+ new_project.build_timeout = 3600
75
+ new_project.ci_config_path = ''
76
+ new_project.ci_forward_deployment_enabled = false
77
+ new_project.container_expiration_policy = {
78
+ "cadence" => 'id',
79
+ "enabled" => false,
80
+ "keep_n" => 10,
81
+ "older_than" => '90d',
82
+ "name_regex" => '.*',
83
+ "name_regex_keep" => nil
84
+ }
85
+ new_project.container_registry_access_level = 'disabled'
86
+ new_project.container_registry_enabled = false
87
+ new_project.emails_disabled = false
88
+ new_project.emails_enabled = true
89
+ new_project.environments_access_level = 'disabled'
90
+ new_project.external_authorization_classification_label = ''
91
+ new_project.feature_flags_access_level = 'disabled'
92
+ new_project.forking_access_level = 'disabled'
93
+ new_project.group_runners_enabled = false
94
+ new_project.infrastructure_access_level = 'disabled'
95
+ new_project.issues_enabled = false
96
+ new_project.jobs_enabled = false
97
+ new_project.lfs_enabled = false
98
+ new_project.merge_method = 'merge'
99
+ new_project.merge_pipelines_enabled = false
100
+ new_project.merge_requests_enabled = true
101
+ new_project.merge_trains_enabled = false
102
+ new_project.merge_trains_skip_train_allowed = false
103
+ new_project.mirror = false
104
+ new_project.model_experiments_access_level = 'disabled'
105
+ new_project.model_registry_access_level = 'disabled'
106
+ new_project.monitor_access_level = 'disabled'
107
+ new_project.only_allow_merge_if_all_discussions_are_resolved = false
108
+ new_project.only_allow_merge_if_pipeline_succeeds = false
109
+ new_project.packages_enabled = false
110
+ new_project.pages_access_level = 'disabled'
111
+ new_project.printing_merge_request_link_enabled = true
112
+ new_project.public_jobs = true
113
+ new_project.releases_access_level = 'disabled'
114
+ new_project.remove_source_branch_after_merge = true
115
+ new_project.request_access_enabled = false
116
+ new_project.requirements_access_level = 'disabled'
117
+ new_project.requirements_enabled = false
118
+ new_project.resolve_outdated_diff_discussions = false
119
+ new_project.security_and_compliance_access_level = 'disabled'
120
+ new_project.service_desk_enabled = false
121
+ new_project.shared_runners_enabled = false
122
+ new_project.snippets_enabled = false
123
+ new_project.squash_option = 'default_off'
124
+ new_project.visibility = private
125
+ new_project.warn_about_potentially_unwanted_characters = true
126
+ new_project.wiki_enabled = false
127
+ Readiness::GitLab::Projects.create!(@gitlab_client, new_project)
128
+ end
129
+
130
+ ##
131
+ # Creates the CMP project's webhook
132
+ #
133
+ # @author Jason Colyer
134
+ # @since 1.0.124
135
+ def self.create_webhook
136
+ token = ENV.fetch('CMP_TOKEN')
137
+ new_hook = Readiness::GitLab::ProjectWebhooks.new
138
+ new_hook.url = "https://gitlab.com/api/v4/projects/39250741/ref/master/trigger/pipeline?token=#{token}&variables[PROJECT_ID]=#{@project.id}"
139
+ new_hook.push_events = true
140
+ new_hook.alert_status = 'executable'
141
+ new_hook.push_events_branch_filter = 'master'
142
+ new_hook.branch_filter_strategy = 'wildcard'
143
+ new_hook.project_id = @project.id
144
+ Readiness::GitLab::ProjectWebhooks.create!(@gitlab_client, new_hook)
145
+ end
146
+
147
+ ##
148
+ # Makes a commit to populate contacts.yaml
149
+ #
150
+ # @author Jason Colyer
151
+ # @since 1.0.124
152
+ def self.populate_contacts_file
153
+ commit_params = {
154
+ branch: 'master',
155
+ commit_message: 'Populating initial contacts',
156
+ actions: [
157
+ {
158
+ file_path: 'contacts.yaml',
159
+ content: yaml_contents,
160
+ action: 'create'
161
+ }
162
+ ]
163
+ }
164
+ Readiness::GitLab::Repositories.create_commit!(@gitlab_client, @project, commit_params)
165
+ end
166
+
167
+ ##
168
+ # Makes a commit to populate README.md
169
+ #
170
+ # @author Jason Colyer
171
+ # @since 1.0.124
172
+ def self.create_readme_file
173
+ commit_params = {
174
+ branch: 'master',
175
+ commit_message: 'Creating CONTACTS.md file',
176
+ actions: [
177
+ {
178
+ file_path: 'CONTACTS.md',
179
+ content: readme_contents,
180
+ action: 'create'
181
+ }
182
+ ]
183
+ }
184
+ Readiness::GitLab::Repositories.create_commit!(@gitlab_client, @project, commit_params)
185
+ end
186
+
187
+ ##
188
+ # Returns the contents for the contacts.yaml file
189
+ #
190
+ # @author Jason Colyer
191
+ # @since 1.0.124
192
+ def self.yaml_contents
193
+ {
194
+ 'org_id' => organization.id,
195
+ 'contacts' => organization_users.map { |a| { "name" => a.name, "email" => a.email } }
196
+ }.to_yaml
197
+ end
198
+
199
+ ##
200
+ # Returns the contents for the README.md file
201
+ #
202
+ # @author Jason Colyer
203
+ # @since 1.0.124
204
+ def self.readme_contents
205
+ <<~STRING
206
+ # Zendesk Global Organization Contact Syncing
207
+
208
+ For more information, please see [our documentation](https://support.gitlab.com/hc/en-us/articles/14142703050396-Contact-Management-Projects)
209
+
210
+ ## What should I do if it didn’t work?
211
+
212
+ Please open a ticket with ops:
213
+
214
+ https://support.gitlab.com/hc/en-us/requests/new?ticket_form_id=360001801419
215
+ STRING
216
+ end
217
+
218
+ ##
219
+ # Creates project invitations
220
+ #
221
+ # @author Jason Colyer
222
+ # @since 1.0.124
223
+ def self.send_invitations
224
+ @email_list.each do |e|
225
+ data = {
226
+ email: e,
227
+ access_level: 30
228
+ }
229
+ Readiness::GitLab::Projects.create_invitation!(@gitlab_client, @project, data)
230
+ end
231
+ end
232
+
233
+ ##
234
+ # Adds the CMP ID to the organization
235
+ #
236
+ # @author Jason Colyer
237
+ # @since 1.0.124
238
+ def self.update_organization
239
+ new_org = Readiness::Zendesk::Organizations.new
240
+ new_org.id = organization.id
241
+ new_org.organization_fields = {
242
+ cmp_id: @project.id
243
+ }
244
+ Readiness::Zendesk::Organizations.update!(@zendesk_client, new_org)
245
+ end
246
+
247
+ ##
248
+ # Updates the ticket
249
+ #
250
+ # @author Jason Colyer
251
+ # @since 1.0.124
252
+ def self.update_ticket
253
+ new_ticket = Readiness::Zendesk::Tickets.new
254
+ new_ticket.id = ticket.id
255
+ new_ticket.status = 'pending'
256
+ new_ticket.comment = {
257
+ body: ticket_comment
258
+ }
259
+ Readiness::Zendesk::Tickets.update!(@zendesk_client, new_ticket)
260
+ end
261
+
262
+ ##
263
+ # Returns the contents for the ticket comment
264
+ #
265
+ # @author Jason Colyer
266
+ # @since 1.0.124
267
+ def self.ticket_comment
268
+ <<~STRING
269
+ Greetings,
270
+
271
+ We have setup your contact management project at this time. You can find it at #{@project.web_url}
272
+
273
+ Any developer without a gitlab.com account should receive an email for the invitation to the project. Any developer with a gitlab.com should be auto-added.
274
+
275
+ We have seeded the contacts.yaml file with your organization's current contact list to help get you started.
276
+
277
+ Please let us know if you encounter any issues in the use of the contacts management project.
278
+ STRING
279
+ end
280
+ end
281
+ end
282
+ end
@@ -9,6 +9,7 @@ module Readiness
9
9
  module TicketProcessor
10
10
  require "#{__dir__}/ticket_processor/2fa_removal"
11
11
  require "#{__dir__}/ticket_processor/account_blocked"
12
+ require "#{__dir__}/ticket_processor/cmp_creation"
12
13
  require "#{__dir__}/ticket_processor/code_request_advanced_sast"
13
14
  require "#{__dir__}/ticket_processor/email_suppressions"
14
15
  require "#{__dir__}/ticket_processor/link_tagger"
@@ -0,0 +1,156 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Defines the module Readiness.
4
+ module Readiness
5
+ # Defines the module Zendesk
6
+ module Zendesk
7
+ ##
8
+ # Defines the class OAuthClients within the module {Readiness::Zendesk}.
9
+ #
10
+ # @author Jason Colyer
11
+ # @since 1.0.125
12
+ # @todo create - https://developer.zendesk.com/api-reference/ticketing/oauth/oauth_clients/#create-client
13
+ # @todo update - https://developer.zendesk.com/api-reference/ticketing/oauth/oauth_clients/#update-client
14
+ # @todo delete - https://developer.zendesk.com/api-reference/ticketing/oauth/oauth_clients/#delete-client
15
+ # @todo generate secret - https://developer.zendesk.com/api-reference/ticketing/oauth/oauth_clients/#delete-client
16
+ class OAuthClients < Readiness::Client
17
+ attr_accessor :company, :created_at, :description, :id, :identifier, :name, :redirect_uri, :secret, :unique_id, :updated_at, :user_id
18
+
19
+ ##
20
+ # Creates a new {Readiness::Zendesk::OAuthClients} instance
21
+ #
22
+ # @author Jason Colyer
23
+ # @since 1.0.125
24
+ # @param object [Object] An instance of {Readiness::Zendesk::OAuthClients}
25
+ # @example
26
+ # require 'support_readiness'
27
+ # Readiness::Zendesk::OAuthClients.new
28
+ def initialize(object = {})
29
+ @company = object['company']
30
+ @created_at = object['created_at']
31
+ @description = object['description']
32
+ @id = object['id']
33
+ @identifier = object['identifier']
34
+ @name = object['name']
35
+ @redirect_uri = object['redirect_uri']
36
+ @secret = object['secret']
37
+ @unique_id = object['unique_id']
38
+ @updated_at = object['updated_at']
39
+ @user_id = object['user_id']
40
+ end
41
+
42
+ ##
43
+ # Lists all OAuth clients.
44
+ #
45
+ # @author Jason Colyer
46
+ # @since 1.0.125
47
+ # @param client [Object] An instance of {Readiness::Zendesk::Client}
48
+ # @return [Array]
49
+ # @see https://developer.zendesk.com/api-reference/ticketing/oauth/oauth_clients/#list-clients Zendesk API > OAuth Clients > List Clients
50
+ # @example
51
+ # require 'support_readiness'
52
+ # config = Readiness::Zendesk::Configuration.new
53
+ # config.username = 'alice@example.com'
54
+ # config.token = 'test123abc'
55
+ # config.url = 'https://example.zendesk.com/api/v2'
56
+ # client = Readiness::Zendesk::Client.new(config)
57
+ # oauth_clients = Readiness::Zendesk::OAuthClients.list(client)
58
+ # pp oauth_clients.count
59
+ # # => 12
60
+ def self.list(client)
61
+ array = []
62
+ opts = 'page[size]=100'
63
+ loop do
64
+ response = client.connection.get("oauth/clients?#{opts}")
65
+ handle_request_error(0, 'Zendesk', response.status) unless response.status == 200
66
+ body = Oj.load(response.body)
67
+ array += body['clients'].map { |c| OAuthClients.new(c) }
68
+ break unless body['meta']['has_more']
69
+
70
+ opts = body['links']['next'].split('?').last
71
+ end
72
+ array
73
+ end
74
+
75
+ ##
76
+ # Locates an OAuth client within Zendesk. This will not exit on error (except Authentication errors)
77
+ #
78
+ # @author Jason Colyer
79
+ # @since 1.0.125
80
+ # @param client [Object] An instance of {Readiness::Zendesk::Client}
81
+ # @param cid [Integer[ The OAuth client ID to find
82
+ # @param return [Hash]
83
+ # @see https://developer.zendesk.com/api-reference/ticketing/oauth/oauth_clients/#show-client Zendesk API > OAuth Clients > Show Client
84
+ # @example
85
+ # require 'support_readiness'
86
+ # config = Readiness::Zendesk::Configuration.new
87
+ # config.username = 'alice@example.com'
88
+ # config.token = 'test123abc'
89
+ # config.url = 'https://example.zendesk.com/api/v2'
90
+ # client = Readiness::Zendesk::Client.new(config)
91
+ # oauth_client = Readiness::Zendesk::OAuthClients.find(client, 223443)
92
+ # pp oauth_client.name
93
+ # # => "Test Client"
94
+ def self.find(client, cid)
95
+ response = client.connection.get("oauth/clients/#{cid}")
96
+ handle_request_error(0, 'Zendesk', response.status, { action: 'get', id: cid }) unless response.status == 200
97
+ return OAuthClients.new(Oj.load(response.body)['client']) if response.status == 200
98
+
99
+ Oj.load(response.body)
100
+ end
101
+
102
+ ##
103
+ # Locates an OAuth client within Zendesk. This will exit on error
104
+ #
105
+ # @author Jason Colyer
106
+ # @since 1.0.125
107
+ # @param client [Object] An instance of {Readiness::Zendesk::Client}
108
+ # @param cid [Integer[ The OAuth client ID to find
109
+ # @param return [Hash]
110
+ # @see https://developer.zendesk.com/api-reference/ticketing/oauth/oauth_clients/#show-client Zendesk API > OAuth Clients > Show Client
111
+ # @example
112
+ # require 'support_readiness'
113
+ # config = Readiness::Zendesk::Configuration.new
114
+ # config.username = 'alice@example.com'
115
+ # config.token = 'test123abc'
116
+ # config.url = 'https://example.zendesk.com/api/v2'
117
+ # client = Readiness::Zendesk::Client.new(config)
118
+ # oauth_client = Readiness::Zendesk::OAuthClients.find!(client, 223443)
119
+ # pp oauth_client.name
120
+ # # => "Test Client"
121
+ def self.find!(client, cid)
122
+ response = client.connection.get("oauth/clients/#{cid}")
123
+ handle_request_error(1, 'Zendesk', response.status, { action: 'Find OAuth client', id: cid }) unless response.status == 200
124
+ OAuthClients.new(Oj.load(response.body)['client'])
125
+ end
126
+
127
+ ##
128
+ # Locates an OAuth client within Zendesk by name. Can utilize a cache for quicker results
129
+ #
130
+ # @author Jason Colyer
131
+ # @since 1.0.125
132
+ # @param client [Object] An instance of {Readiness::Zendesk::Client}
133
+ # @param name [String] The OAuth client name to look for
134
+ # @param cache [Array] The results of {Readiness::Zendesk::OAuthClients#list}
135
+ # @return [Object] An instance of {Readiness::Zendesk::OAuthClients}
136
+ # @example
137
+ # require 'support_readiness'
138
+ # config = Readiness::Zendesk::Configuration.new
139
+ # config.username = 'alice@example.com'
140
+ # config.token = 'test123abc'
141
+ # config.url = 'https://example.zendesk.com/api/v2'
142
+ # client = Readiness::Zendesk::Client.new(config)
143
+ # oauth_client = Readiness::Zendesk::OAuthClients.find_by_name(client, 'Test Client')
144
+ # pp oauth_client.id
145
+ # # => 223443
146
+ def self.find_by_name(client, name, cache = nil)
147
+ oauth_clients = if cache.nil?
148
+ OAuthClients.list(client)
149
+ else
150
+ cache
151
+ end
152
+ oauth_clients.detect { |o| o.name == name }
153
+ end
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Defines the module Readiness.
4
+ module Readiness
5
+ # Defines the module Zendesk
6
+ module Zendesk
7
+ ##
8
+ # Defines the class OAuthTokens within the module {Readiness::Zendesk}.
9
+ #
10
+ # @author Jason Colyer
11
+ # @since 1.0.125
12
+ # @todo list - https://developer.zendesk.com/api-reference/ticketing/oauth/oauth_tokens/#list-tokens
13
+ # @todo show - https://developer.zendesk.com/api-reference/ticketing/oauth/oauth_tokens/#show-token
14
+ # @todo revoke - https://developer.zendesk.com/api-reference/ticketing/oauth/oauth_tokens/#revoke-token
15
+ class OAuthTokens < Readiness::Client
16
+ attr_accessor :client_id, :created_at, :expires_at, :full_token, :id, :refresh_token, :refresh_token_expires_at, :scopes, :token, :used_at, :user_id
17
+
18
+ ##
19
+ # Creates a new {Readiness::Zendesk::OAuthTokens} instance
20
+ #
21
+ # @author Jason Colyer
22
+ # @since 1.0.125
23
+ # @param object [Object] An instance of {Readiness::Zendesk::OAuthTokens}
24
+ # @example
25
+ # require 'support_readiness'
26
+ # Readiness::Zendesk::OAuthTokens.new
27
+ def initialize(object = {})
28
+ @client_id = object['client_id']
29
+ @created_at = object['created_at']
30
+ @expires_at = object['expires_at']
31
+ @full_token = object['full_token']
32
+ @id = object['id']
33
+ @refresh_token = object['refresh_token']
34
+ @refresh_token_expires_at = object['refresh_token_expires_at']
35
+ @scopes = object['scopes']
36
+ @token = object['token']
37
+ @used_at = object['used_at']
38
+ @user_id = object['user_id']
39
+ end
40
+
41
+ ##
42
+ # Creates an Oauth token. Will exit if unsuccessful.
43
+ #
44
+ # @author Jason Colyer
45
+ # @since 1.0.125
46
+ # @param client [Object] An instance of {Readiness::Zendesk::Client}
47
+ # @param token [Object] An instance of {Readiness::Zendesk::OAuthTokens}
48
+ # @return [Object] An instance of {Readiness::Zendesk::OAuthTokens}
49
+ # @see https://developer.zendesk.com/api-reference/ticketing/oauth/oauth_tokens/#create-token Zendesk API > OAuth Tokens > Create Token
50
+ # @example
51
+ # require 'support_readiness'
52
+ # config = Readiness::Zendesk::Configuration.new
53
+ # config.username = 'alice@example.com'
54
+ # config.token = 'test123abc'
55
+ # config.url = 'https://example.zendesk.com/api/v2'
56
+ # client = Readiness::Zendesk::Client.new(config)
57
+ # token = Readiness::Zendesk::OAuthTokens.new
58
+ # token.client_id = 1234
59
+ # token.scopes = [
60
+ # 'impersonate',
61
+ # 'write'
62
+ # ]
63
+ # create = Readiness::Zendesk::OAuthTokens.create!(client, token)
64
+ # pp create.full_token
65
+ # # => "4v8AR9vXCM7dV4murXlIaBAAzDrAw9lIbaHF7X9VbVPtOABAyy3dnTtHE3A6AdNC"
66
+ def self.create!(client, token)
67
+ pp to_clean_json_with_key(token, 'token')
68
+ response = client.connection.post 'oauth/tokens', to_clean_json_with_key(token, 'token')
69
+ handle_request_error(1, 'Zendesk', response.status, { action: 'Create Oauth token', message: Oj.load(response.body)}) unless response.status == 201
70
+ OAuthTokens.new(Oj.load(response.body)['token'])
71
+ end
72
+ end
73
+ end
74
+ end
@@ -927,6 +927,58 @@ module Readiness
927
927
  end
928
928
  true
929
929
  end
930
+
931
+ ##
932
+ # Add a satisfaction rating to a ticket (must be done using end-user as the config.username). Will exit if unsuccessful
933
+ #
934
+ # @author Jason Colyer
935
+ # @since NEW_VERSION
936
+ # @param client [Object] An instance of {Readiness::Zendesk::Client}
937
+ # @param ticket [Object] An instance of {Readiness::Zendesk::Tickets}
938
+ # @param score [String] The score to use ('good' or 'bad' is the normal usage)
939
+ # @param comment [String] The comment to use
940
+ # @return [Hash]
941
+ # @see https://developer.zendesk.com/api-reference/ticketing/ticket-management/satisfaction_ratings/#create-a-satisfaction-rating Zendesk API > Satisfaction Ratings > Create a Satisfaction Rating
942
+ # @example
943
+ # require 'support_readiness'
944
+ # config = Readiness::Zendesk::Configuration.new
945
+ # config.username = 'alice@example.com'
946
+ # config.token = 'test123abc'
947
+ # config.url = 'https://example.zendesk.com/api/v2'
948
+ # client = Readiness::Zendesk::Client.new(config)
949
+ # ticket = Readiness::Zendesk::Tickets.find!(client, 141)
950
+ # user = Readiness::Zendesk::Users.find!(client, 123456)
951
+ # oauth_client = Readiness::Zendesk::OAuthClients.find_by_name(client, 'Test App')
952
+ # new_token = Readiness::Zendesk::OAuthTokens.new
953
+ # new_token.client_id = oauth_client.id
954
+ # new_token.scopes = [
955
+ # 'impersonate',
956
+ # 'write'
957
+ # ]
958
+ # oauth_token = Readiness::Zendesk::OAuthTokens.create!(client, new_token)
959
+ # user_client = Faraday.new(client.url) do |c|
960
+ # c.request :retry, {
961
+ # max: client.retry_max,
962
+ # interval: sb_zendesk_config.retry_interval,
963
+ # interval_randomness: client.retry_randomness,
964
+ # backoff_factor: client.retry_backoff,
965
+ # exceptions: client.retry_exceptions
966
+ # }
967
+ # c.adapter Faraday.default_adapter
968
+ # c.headers['Content-Type'] = 'application/json'
969
+ # c.headers['Authorization'] = "Bearer #{oauth_token.full_token}"
970
+ # c.headers['X-On-Behalf-Of'] = user.email
971
+ # end
972
+ # rating = Readiness::Zendesk::Tickets.create_satisfaction_score!(user_client, ticket, 'good', 'jason is awesome!')
973
+ # pp rating['score']
974
+ # # => "good"
975
+ def self.create_satisfaction_score!(client, ticket, score, comment)
976
+ data = { satisfaction_rating: { score: score, comment: comment }}.to_json
977
+ response = client.post "tickets/#{ticket.id}/satisfaction_rating", data
978
+ pp response.body
979
+ handle_request_error(1, 'Zendesk', response.status, { action: 'Add satisfaction rating', message: Oj.load(response.body)}) unless response.status == 200
980
+ Oj.load(response.body)['satisfaction_rating']
981
+ end
930
982
  end
931
983
  end
932
984
  end
@@ -21,6 +21,8 @@ module Readiness
21
21
  require "#{__dir__}/zendesk/job_statuses"
22
22
  require "#{__dir__}/zendesk/locales"
23
23
  require "#{__dir__}/zendesk/macros"
24
+ require "#{__dir__}/zendesk/oauth_clients"
25
+ require "#{__dir__}/zendesk/oauth_tokens"
24
26
  require "#{__dir__}/zendesk/organization_fields"
25
27
  require "#{__dir__}/zendesk/organization_memberships"
26
28
  require "#{__dir__}/zendesk/organizations"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab_support_readiness
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.123
4
+ version: 1.0.125
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Colyer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-02-18 00:00:00.000000000 Z
11
+ date: 2025-02-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -280,6 +280,7 @@ files:
280
280
  - lib/support_readiness/gitlab/merge_requests.rb
281
281
  - lib/support_readiness/gitlab/namespaces.rb
282
282
  - lib/support_readiness/gitlab/pipelines.rb
283
+ - lib/support_readiness/gitlab/project_webhooks.rb
283
284
  - lib/support_readiness/gitlab/projects.rb
284
285
  - lib/support_readiness/gitlab/repositories.rb
285
286
  - lib/support_readiness/gitlab/users.rb
@@ -393,6 +394,7 @@ files:
393
394
  - lib/support_readiness/ticket_processor.rb
394
395
  - lib/support_readiness/ticket_processor/2fa_removal.rb
395
396
  - lib/support_readiness/ticket_processor/account_blocked.rb
397
+ - lib/support_readiness/ticket_processor/cmp_creation.rb
396
398
  - lib/support_readiness/ticket_processor/code_request_advanced_sast.rb
397
399
  - lib/support_readiness/ticket_processor/email_suppressions.rb
398
400
  - lib/support_readiness/ticket_processor/link_tagger.rb
@@ -416,6 +418,8 @@ files:
416
418
  - lib/support_readiness/zendesk/job_statuses.rb
417
419
  - lib/support_readiness/zendesk/locales.rb
418
420
  - lib/support_readiness/zendesk/macros.rb
421
+ - lib/support_readiness/zendesk/oauth_clients.rb
422
+ - lib/support_readiness/zendesk/oauth_tokens.rb
419
423
  - lib/support_readiness/zendesk/organization_fields.rb
420
424
  - lib/support_readiness/zendesk/organization_memberships.rb
421
425
  - lib/support_readiness/zendesk/organizations.rb