foreman_webhooks 3.0.5 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/foreman_webhooks/locale/ca/foreman_webhooks.js +238 -0
- data/app/assets/javascripts/foreman_webhooks/locale/cs_CZ/foreman_webhooks.js +238 -0
- data/app/assets/javascripts/foreman_webhooks/locale/de/foreman_webhooks.js +238 -0
- data/app/assets/javascripts/foreman_webhooks/locale/en/foreman_webhooks.js +262 -0
- data/app/assets/javascripts/foreman_webhooks/locale/en_GB/foreman_webhooks.js +238 -0
- data/app/assets/javascripts/foreman_webhooks/locale/es/foreman_webhooks.js +238 -0
- data/app/assets/javascripts/foreman_webhooks/locale/fr/foreman_webhooks.js +238 -0
- data/app/assets/javascripts/foreman_webhooks/locale/it/foreman_webhooks.js +238 -0
- data/app/assets/javascripts/foreman_webhooks/locale/ja/foreman_webhooks.js +238 -0
- data/app/assets/javascripts/foreman_webhooks/locale/ka/foreman_webhooks.js +238 -0
- data/app/assets/javascripts/foreman_webhooks/locale/ko/foreman_webhooks.js +238 -0
- data/app/assets/javascripts/foreman_webhooks/locale/pl/foreman_webhooks.js +238 -0
- data/app/assets/javascripts/foreman_webhooks/locale/pt_BR/foreman_webhooks.js +238 -0
- data/app/assets/javascripts/foreman_webhooks/locale/ru/foreman_webhooks.js +238 -0
- data/app/assets/javascripts/foreman_webhooks/locale/zh_CN/foreman_webhooks.js +238 -0
- data/app/assets/javascripts/foreman_webhooks/locale/zh_TW/foreman_webhooks.js +238 -0
- data/app/controllers/api/v2/webhooks_controller.rb +24 -1
- data/app/graphql/foreman_webhooks/types/webhook.rb +25 -0
- data/app/graphql/foreman_webhooks/types/webhook_template.rb +25 -0
- data/app/models/webhook.rb +18 -0
- data/app/models/webhook_template.rb +2 -0
- data/app/services/foreman_webhooks/webhook_service.rb +1 -1
- data/app/views/foreman_webhooks/webhook_templates/katello_-_promote.erb +1 -1
- data/app/views/foreman_webhooks/webhook_templates/katello_-_publish.erb +1 -1
- data/app/views/foreman_webhooks/webhook_templates/katello_-_repo_sync.erb +1 -1
- data/config/routes.rb +3 -0
- data/lib/foreman_webhooks/engine.rb +9 -2
- data/lib/foreman_webhooks/version.rb +1 -1
- data/locale/ca/LC_MESSAGES/foreman_webhooks.mo +0 -0
- data/locale/ca/foreman_webhooks.po +237 -0
- data/locale/cs_CZ/LC_MESSAGES/foreman_webhooks.mo +0 -0
- data/locale/cs_CZ/foreman_webhooks.po +240 -0
- data/locale/de/LC_MESSAGES/foreman_webhooks.mo +0 -0
- data/locale/de/foreman_webhooks.po +244 -0
- data/locale/en/LC_MESSAGES/foreman_webhooks.mo +0 -0
- data/locale/en/foreman_webhooks.po +258 -0
- data/locale/en_GB/LC_MESSAGES/foreman_webhooks.mo +0 -0
- data/locale/en_GB/foreman_webhooks.po +239 -0
- data/locale/es/LC_MESSAGES/foreman_webhooks.mo +0 -0
- data/locale/es/foreman_webhooks.po +241 -0
- data/locale/fr/LC_MESSAGES/foreman_webhooks.mo +0 -0
- data/locale/fr/foreman_webhooks.po +241 -0
- data/locale/it/LC_MESSAGES/foreman_webhooks.mo +0 -0
- data/locale/it/foreman_webhooks.po +240 -0
- data/locale/ja/LC_MESSAGES/foreman_webhooks.mo +0 -0
- data/locale/ja/foreman_webhooks.po +240 -0
- data/locale/ka/LC_MESSAGES/foreman_webhooks.mo +0 -0
- data/locale/ka/foreman_webhooks.po +237 -0
- data/locale/ko/LC_MESSAGES/foreman_webhooks.mo +0 -0
- data/locale/ko/foreman_webhooks.po +238 -0
- data/locale/pl/LC_MESSAGES/foreman_webhooks.mo +0 -0
- data/locale/pl/foreman_webhooks.po +240 -0
- data/locale/pt_BR/LC_MESSAGES/foreman_webhooks.mo +0 -0
- data/locale/pt_BR/foreman_webhooks.po +241 -0
- data/locale/ru/LC_MESSAGES/foreman_webhooks.mo +0 -0
- data/locale/ru/foreman_webhooks.po +241 -0
- data/locale/zh_CN/LC_MESSAGES/foreman_webhooks.mo +0 -0
- data/locale/zh_CN/foreman_webhooks.po +240 -0
- data/locale/zh_TW/LC_MESSAGES/foreman_webhooks.mo +0 -0
- data/locale/zh_TW/foreman_webhooks.po +239 -0
- data/package.json +0 -3
- data/test/factories/webhook_template.rb +10 -0
- data/test/graphql/foreman_webhooks/queries/webhook_query_test.rb +59 -0
- data/test/graphql/foreman_webhooks/queries/webhook_template_query_test.rb +64 -0
- data/test/graphql/foreman_webhooks/queries/webhook_templates_query_test.rb +47 -0
- data/test/graphql/foreman_webhooks/queries/webhooks_query_test.rb +47 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/Components/WebhookForm/Components/WebhookFormTabs.js +19 -4
- data/webpack/ForemanWebhooks/Routes/Webhooks/Components/WebhookForm/WebhookFormSelectors.js +4 -5
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhookTestModal.js +100 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/Components/ActionButtons/ActionButton.js +40 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/Components/Formatters/actionCellFormatter.js +20 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/Components/Formatters/index.js +1 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/WebhooksTable.js +7 -3
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/WebhooksTableSchema.js +3 -4
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/__tests__/WebhooksTable.test.js +2 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/__tests__/__snapshots__/WebhooksTable.test.js.snap +32 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/Components/WebhooksTable/index.js +23 -2
- data/webpack/ForemanWebhooks/Routes/Webhooks/WebhooksIndexPage/WebhooksIndexPage.js +3 -0
- data/webpack/ForemanWebhooks/Routes/Webhooks/constants.js +1 -0
- data/webpack/__mocks__/foremanReact/components/common/ActionButtons/ActionButtons.js +3 -0
- metadata +95 -7
- data/test/factories/webhook_target.rb +0 -9
@@ -0,0 +1,239 @@
|
|
1
|
+
# SOME DESCRIPTIVE TITLE.
|
2
|
+
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
3
|
+
# This file is distributed under the same license as the foreman_webhooks package.
|
4
|
+
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
5
|
+
#
|
6
|
+
# Translators:
|
7
|
+
# Bryan Kearney <bryan.kearney@gmail.com>, 2023
|
8
|
+
# 0868a4d1af5275b3f70b0a6dac4c99a4, 2023
|
9
|
+
#
|
10
|
+
#, fuzzy
|
11
|
+
msgid ""
|
12
|
+
msgstr ""
|
13
|
+
"Project-Id-Version: foreman_webhooks 3.2.0\n"
|
14
|
+
"Report-Msgid-Bugs-To: \n"
|
15
|
+
"PO-Revision-Date: 2023-06-05 12:44+0000\n"
|
16
|
+
"Last-Translator: 0868a4d1af5275b3f70b0a6dac4c99a4, 2023\n"
|
17
|
+
"Language-Team: Chinese (Taiwan) (https://app.transifex.com/foreman/teams/114/z"
|
18
|
+
"h_TW/)\n"
|
19
|
+
"MIME-Version: 1.0\n"
|
20
|
+
"Content-Type: text/plain; charset=UTF-8\n"
|
21
|
+
"Content-Transfer-Encoding: 8bit\n"
|
22
|
+
"Language: zh_TW\n"
|
23
|
+
"Plural-Forms: nplurals=1; plural=0;\n"
|
24
|
+
|
25
|
+
msgid "Actions"
|
26
|
+
msgstr "動作"
|
27
|
+
|
28
|
+
msgid "Additional"
|
29
|
+
msgstr ""
|
30
|
+
|
31
|
+
msgid "Authentication credentials"
|
32
|
+
msgstr ""
|
33
|
+
|
34
|
+
msgid "Authorize with Foreman client certificate and validate smart-proxy CA from Settings"
|
35
|
+
msgstr ""
|
36
|
+
|
37
|
+
msgid "Change the password"
|
38
|
+
msgstr ""
|
39
|
+
|
40
|
+
msgid "Clone a template"
|
41
|
+
msgstr ""
|
42
|
+
|
43
|
+
msgid "Confirm Webhook Deletion"
|
44
|
+
msgstr ""
|
45
|
+
|
46
|
+
msgid "Create Template"
|
47
|
+
msgstr ""
|
48
|
+
|
49
|
+
msgid "Create Webhook"
|
50
|
+
msgstr ""
|
51
|
+
|
52
|
+
msgid "Create a Webhook"
|
53
|
+
msgstr ""
|
54
|
+
|
55
|
+
msgid "Create a webhook template"
|
56
|
+
msgstr ""
|
57
|
+
|
58
|
+
msgid "Credentials"
|
59
|
+
msgstr ""
|
60
|
+
|
61
|
+
msgid "Delete"
|
62
|
+
msgstr "刪除"
|
63
|
+
|
64
|
+
msgid "Delete a Webhook"
|
65
|
+
msgstr ""
|
66
|
+
|
67
|
+
msgid "Delete a webhook template"
|
68
|
+
msgstr ""
|
69
|
+
|
70
|
+
msgid "Deliver webhook"
|
71
|
+
msgstr ""
|
72
|
+
|
73
|
+
msgid "Deliver webhook %s"
|
74
|
+
msgstr ""
|
75
|
+
|
76
|
+
msgid "Edit"
|
77
|
+
msgstr "編輯"
|
78
|
+
|
79
|
+
msgid "Edit %s"
|
80
|
+
msgstr ""
|
81
|
+
|
82
|
+
msgid "Enabled"
|
83
|
+
msgstr ""
|
84
|
+
|
85
|
+
msgid "Error"
|
86
|
+
msgstr ""
|
87
|
+
|
88
|
+
msgid "Example: %s"
|
89
|
+
msgstr ""
|
90
|
+
|
91
|
+
msgid "Export a webhook template to ERB"
|
92
|
+
msgstr ""
|
93
|
+
|
94
|
+
msgid "General"
|
95
|
+
msgstr "一般"
|
96
|
+
|
97
|
+
msgid "HTTP Content Type"
|
98
|
+
msgstr ""
|
99
|
+
|
100
|
+
msgid "HTTP Headers"
|
101
|
+
msgstr ""
|
102
|
+
|
103
|
+
msgid "HTTP Method"
|
104
|
+
msgstr ""
|
105
|
+
|
106
|
+
msgid "If unchecked, the webhook will be inactive"
|
107
|
+
msgstr ""
|
108
|
+
|
109
|
+
msgid "Import a webhook template"
|
110
|
+
msgstr ""
|
111
|
+
|
112
|
+
msgid "List Webhooks"
|
113
|
+
msgstr ""
|
114
|
+
|
115
|
+
msgid "List available events for subscription"
|
116
|
+
msgstr ""
|
117
|
+
|
118
|
+
msgid "List webhook templates"
|
119
|
+
msgstr ""
|
120
|
+
|
121
|
+
msgid "Name"
|
122
|
+
msgstr "名稱"
|
123
|
+
|
124
|
+
msgid "No Results"
|
125
|
+
msgstr ""
|
126
|
+
|
127
|
+
msgid "Optional CAs in PEM format concatenated to verify the receiver's SSL certificate"
|
128
|
+
msgstr ""
|
129
|
+
|
130
|
+
msgid "Optional. Must be a JSON object (ERB allowed)"
|
131
|
+
msgstr ""
|
132
|
+
|
133
|
+
msgid "Password"
|
134
|
+
msgstr ""
|
135
|
+
|
136
|
+
msgid "Proxy Authorization"
|
137
|
+
msgstr ""
|
138
|
+
|
139
|
+
msgid "Show Webhook details"
|
140
|
+
msgstr ""
|
141
|
+
|
142
|
+
msgid "Show webhook template details"
|
143
|
+
msgstr ""
|
144
|
+
|
145
|
+
msgid "Snippet"
|
146
|
+
msgstr ""
|
147
|
+
|
148
|
+
msgid "Start typing to search"
|
149
|
+
msgstr ""
|
150
|
+
|
151
|
+
msgid "Subscribe to"
|
152
|
+
msgstr ""
|
153
|
+
|
154
|
+
msgid "Target URL"
|
155
|
+
msgstr ""
|
156
|
+
|
157
|
+
msgid "Target URL that should be called by Foreman (ERB allowed)."
|
158
|
+
msgstr ""
|
159
|
+
|
160
|
+
msgid "Template"
|
161
|
+
msgstr ""
|
162
|
+
|
163
|
+
msgid "Template contents including metadata"
|
164
|
+
msgstr ""
|
165
|
+
|
166
|
+
msgid "Template name"
|
167
|
+
msgstr ""
|
168
|
+
|
169
|
+
msgid "This template is locked for editing."
|
170
|
+
msgstr ""
|
171
|
+
|
172
|
+
msgid "Try to create a new webhook"
|
173
|
+
msgstr ""
|
174
|
+
|
175
|
+
msgid "Type"
|
176
|
+
msgstr "類型"
|
177
|
+
|
178
|
+
msgid "URL must be valid and schema must be one of: %s"
|
179
|
+
msgstr ""
|
180
|
+
|
181
|
+
msgid "Uncheck this option to disable validation of the receiver's SSL certificate"
|
182
|
+
msgstr ""
|
183
|
+
|
184
|
+
msgid "Update a Webhook"
|
185
|
+
msgstr ""
|
186
|
+
|
187
|
+
msgid "Update a webhook template"
|
188
|
+
msgstr ""
|
189
|
+
|
190
|
+
msgid "User"
|
191
|
+
msgstr "使用者"
|
192
|
+
|
193
|
+
msgid "Verify SSL"
|
194
|
+
msgstr "驗證 SSL"
|
195
|
+
|
196
|
+
msgid "Webhook"
|
197
|
+
msgstr ""
|
198
|
+
|
199
|
+
msgid "Webhook %s was successfully deleted"
|
200
|
+
msgstr ""
|
201
|
+
|
202
|
+
msgid "Webhook Templates"
|
203
|
+
msgstr ""
|
204
|
+
|
205
|
+
msgid "Webhook was successfully created."
|
206
|
+
msgstr ""
|
207
|
+
|
208
|
+
msgid "Webhook was successfully updated."
|
209
|
+
msgstr ""
|
210
|
+
|
211
|
+
msgid "WebhookTemplate|Locked"
|
212
|
+
msgstr ""
|
213
|
+
|
214
|
+
msgid "WebhookTemplate|Name"
|
215
|
+
msgstr ""
|
216
|
+
|
217
|
+
msgid "WebhookTemplate|Snippet"
|
218
|
+
msgstr ""
|
219
|
+
|
220
|
+
msgid "Webhooks"
|
221
|
+
msgstr ""
|
222
|
+
|
223
|
+
msgid "Whether or not the template is added automatically to new organizations and locations"
|
224
|
+
msgstr ""
|
225
|
+
|
226
|
+
msgid "Whether or not the template is locked for editing"
|
227
|
+
msgstr ""
|
228
|
+
|
229
|
+
msgid "X509 Certification Authorities"
|
230
|
+
msgstr ""
|
231
|
+
|
232
|
+
msgid "X509 Certification Authorities concatenated in PEM format"
|
233
|
+
msgstr ""
|
234
|
+
|
235
|
+
msgid "You are about to delete %s. Are you sure?"
|
236
|
+
msgstr ""
|
237
|
+
|
238
|
+
msgid "is required"
|
239
|
+
msgstr ""
|
data/package.json
CHANGED
@@ -9,8 +9,6 @@
|
|
9
9
|
"test:watch": "tfm-test --plugin --watchAll",
|
10
10
|
"test:current": "tfm-test --plugin --watch",
|
11
11
|
"publish-coverage": "tfm-publish-coverage",
|
12
|
-
"stories": "tfm-stories --plugin",
|
13
|
-
"stories:build": "tfm-build-stories --plugin",
|
14
12
|
"create-react-component": "yo react-domain"
|
15
13
|
},
|
16
14
|
"repository": {
|
@@ -26,7 +24,6 @@
|
|
26
24
|
"devDependencies": {
|
27
25
|
"@babel/core": "^7.7.0",
|
28
26
|
"@theforeman/builder": ">= 0",
|
29
|
-
"@theforeman/stories": ">= 0",
|
30
27
|
"@theforeman/test": ">= 0",
|
31
28
|
"@theforeman/vendor-dev": ">= 0",
|
32
29
|
"@theforeman/eslint-plugin-foreman": ">= 0",
|
@@ -12,5 +12,15 @@ FactoryBot.define do
|
|
12
12
|
trait :locked do
|
13
13
|
locked { true }
|
14
14
|
end
|
15
|
+
|
16
|
+
trait :with_webhooks do
|
17
|
+
transient do
|
18
|
+
webhooks_count { 2 }
|
19
|
+
end
|
20
|
+
|
21
|
+
after(:create) do |webhook_template, evaluator|
|
22
|
+
create_list(:webhook, evaluator.webhooks_count, webhook_template: webhook_template)
|
23
|
+
end
|
24
|
+
end
|
15
25
|
end
|
16
26
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_plugin_helper'
|
4
|
+
|
5
|
+
module ForemanWebhooks
|
6
|
+
module Queries
|
7
|
+
class WebhookQueryTest < GraphQLQueryTestCase
|
8
|
+
let(:query) do
|
9
|
+
<<-GRAPHQL
|
10
|
+
query (
|
11
|
+
$id: String!
|
12
|
+
) {
|
13
|
+
webhook(id: $id) {
|
14
|
+
id
|
15
|
+
createdAt
|
16
|
+
updatedAt
|
17
|
+
name
|
18
|
+
targetUrl
|
19
|
+
events
|
20
|
+
httpMethod
|
21
|
+
httpContentType
|
22
|
+
enabled
|
23
|
+
verifySsl
|
24
|
+
sslCaCerts
|
25
|
+
user
|
26
|
+
webhookTemplate {
|
27
|
+
id
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
31
|
+
GRAPHQL
|
32
|
+
end
|
33
|
+
|
34
|
+
let(:webhook) { FactoryBot.create(:webhook) }
|
35
|
+
let(:global_id) { Foreman::GlobalId.for(webhook) }
|
36
|
+
let(:variables) { { id: global_id } }
|
37
|
+
let(:data) { result['data']['webhook'] }
|
38
|
+
|
39
|
+
test 'fetching webhook attributes' do
|
40
|
+
assert_empty result['errors']
|
41
|
+
|
42
|
+
assert_equal global_id, data['id']
|
43
|
+
assert_equal webhook.created_at.utc.iso8601, data['createdAt']
|
44
|
+
assert_equal webhook.updated_at.utc.iso8601, data['updatedAt']
|
45
|
+
assert_equal webhook.name, data['name']
|
46
|
+
assert_equal webhook.target_url, data['targetUrl']
|
47
|
+
assert_equal webhook.events, data['events']
|
48
|
+
assert_equal webhook.http_method, data['httpMethod']
|
49
|
+
assert_equal webhook.http_content_type, data['httpContentType']
|
50
|
+
assert_equal webhook.enabled, data['enabled']
|
51
|
+
assert_equal webhook.verify_ssl, data['verifySsl']
|
52
|
+
assert_equal webhook.ssl_ca_certs, data['sslCaCerts']
|
53
|
+
assert_equal webhook.user, data['user']
|
54
|
+
|
55
|
+
assert_record webhook.webhook_template, data['webhookTemplate']
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_plugin_helper'
|
4
|
+
|
5
|
+
module ForemanWebhooks
|
6
|
+
module Queries
|
7
|
+
class WebhookTemplateQueryTest < GraphQLQueryTestCase
|
8
|
+
let(:query) do
|
9
|
+
<<-GRAPHQL
|
10
|
+
query (
|
11
|
+
$id: String!
|
12
|
+
) {
|
13
|
+
webhookTemplate(id: $id) {
|
14
|
+
id
|
15
|
+
createdAt
|
16
|
+
updatedAt
|
17
|
+
name
|
18
|
+
template
|
19
|
+
vendor
|
20
|
+
type
|
21
|
+
osFamily
|
22
|
+
description
|
23
|
+
snippet
|
24
|
+
locked
|
25
|
+
default
|
26
|
+
webhooks {
|
27
|
+
totalCount
|
28
|
+
edges {
|
29
|
+
node {
|
30
|
+
id
|
31
|
+
}
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
36
|
+
GRAPHQL
|
37
|
+
end
|
38
|
+
|
39
|
+
let(:webhook_template) { FactoryBot.create(:webhook_template, :with_webhooks) }
|
40
|
+
let(:global_id) { Foreman::GlobalId.for(webhook_template) }
|
41
|
+
let(:variables) { { id: global_id } }
|
42
|
+
let(:data) { result['data']['webhookTemplate'] }
|
43
|
+
|
44
|
+
test 'fetching webhook template attributes' do
|
45
|
+
assert_empty result['errors']
|
46
|
+
|
47
|
+
assert_equal global_id, data['id']
|
48
|
+
assert_equal webhook_template.created_at.utc.iso8601, data['createdAt']
|
49
|
+
assert_equal webhook_template.updated_at.utc.iso8601, data['updatedAt']
|
50
|
+
assert_equal webhook_template.name, data['name']
|
51
|
+
assert_equal webhook_template.template, data['template']
|
52
|
+
assert_equal webhook_template.vendor, data['vendor']
|
53
|
+
assert_equal webhook_template.type, data['type']
|
54
|
+
assert_equal webhook_template.os_family, data['osFamily']
|
55
|
+
assert_equal webhook_template.description, data['description']
|
56
|
+
assert_equal webhook_template.snippet, data['snippet']
|
57
|
+
assert_equal webhook_template.locked, data['locked']
|
58
|
+
assert_equal webhook_template.default, data['default']
|
59
|
+
|
60
|
+
assert_collection webhook_template.webhooks, data['webhooks']
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_plugin_helper'
|
4
|
+
|
5
|
+
module ForemanWebhooks
|
6
|
+
module Queries
|
7
|
+
class WebhookTemplatesQueryTest < GraphQLQueryTestCase
|
8
|
+
let(:query) do
|
9
|
+
<<-GRAPHQL
|
10
|
+
query {
|
11
|
+
webhookTemplates {
|
12
|
+
totalCount
|
13
|
+
pageInfo {
|
14
|
+
startCursor
|
15
|
+
endCursor
|
16
|
+
hasNextPage
|
17
|
+
hasPreviousPage
|
18
|
+
}
|
19
|
+
edges {
|
20
|
+
cursor
|
21
|
+
node {
|
22
|
+
id
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
GRAPHQL
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:data) { result['data']['webhookTemplates'] }
|
31
|
+
|
32
|
+
setup do
|
33
|
+
FactoryBot.create(:webhook_template)
|
34
|
+
end
|
35
|
+
|
36
|
+
test 'fetching webhook templates attributes' do
|
37
|
+
assert_empty result['errors']
|
38
|
+
|
39
|
+
expected_count = ::WebhookTemplate.count
|
40
|
+
|
41
|
+
assert_not_equal 0, expected_count
|
42
|
+
assert_equal expected_count, data['totalCount']
|
43
|
+
assert_equal expected_count, data['edges'].count
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_plugin_helper'
|
4
|
+
|
5
|
+
module ForemanWebhooks
|
6
|
+
module Queries
|
7
|
+
class WebhooksQueryTest < GraphQLQueryTestCase
|
8
|
+
let(:query) do
|
9
|
+
<<-GRAPHQL
|
10
|
+
query {
|
11
|
+
webhooks {
|
12
|
+
totalCount
|
13
|
+
pageInfo {
|
14
|
+
startCursor
|
15
|
+
endCursor
|
16
|
+
hasNextPage
|
17
|
+
hasPreviousPage
|
18
|
+
}
|
19
|
+
edges {
|
20
|
+
cursor
|
21
|
+
node {
|
22
|
+
id
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
GRAPHQL
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:data) { result['data']['webhooks'] }
|
31
|
+
|
32
|
+
setup do
|
33
|
+
FactoryBot.create(:webhook)
|
34
|
+
end
|
35
|
+
|
36
|
+
test 'fetching webhooks attributes' do
|
37
|
+
assert_empty result['errors']
|
38
|
+
|
39
|
+
expected_count = ::Webhook.count
|
40
|
+
|
41
|
+
assert_not_equal 0, expected_count
|
42
|
+
assert_equal expected_count, data['totalCount']
|
43
|
+
assert_equal expected_count, data['edges'].count
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/webpack/ForemanWebhooks/Routes/Webhooks/Components/WebhookForm/Components/WebhookFormTabs.js
CHANGED
@@ -2,7 +2,7 @@ import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
3
3
|
import { Tabs, Tab, TabTitleText } from '@patternfly/react-core';
|
4
4
|
|
5
|
-
import { translate as __ } from 'foremanReact/common/I18n';
|
5
|
+
import { sprintf, translate as __ } from 'foremanReact/common/I18n';
|
6
6
|
|
7
7
|
import ForemanFormikField from './ForemanFormikField';
|
8
8
|
|
@@ -48,7 +48,21 @@ const WebhookFormTabs = ({
|
|
48
48
|
type="text"
|
49
49
|
required
|
50
50
|
label={__('Target URL')}
|
51
|
-
labelHelp={
|
51
|
+
labelHelp={
|
52
|
+
<>
|
53
|
+
<div>
|
54
|
+
{__(
|
55
|
+
'Target URL that should be called by Foreman (ERB allowed).'
|
56
|
+
)}
|
57
|
+
</div>
|
58
|
+
<div>
|
59
|
+
{sprintf(
|
60
|
+
__('Example: %s'),
|
61
|
+
'https://host.example.com/inventory/<%= @object.id %>'
|
62
|
+
)}
|
63
|
+
</div>
|
64
|
+
</>
|
65
|
+
}
|
52
66
|
/>
|
53
67
|
<ForemanFormikField
|
54
68
|
name="webhook_template_id"
|
@@ -137,8 +151,9 @@ const WebhookFormTabs = ({
|
|
137
151
|
<ForemanFormikField
|
138
152
|
name="http_headers"
|
139
153
|
type="textarea"
|
140
|
-
label={__('
|
141
|
-
|
154
|
+
label={__('HTTP Headers')}
|
155
|
+
labelHelp={__('Optional. Must be a JSON object (ERB allowed)')}
|
156
|
+
placeholder='{ "X-Shellhook-Arg-1": "value", "X-Shellhook-Arg-2": "<%= @object.id %>" }'
|
142
157
|
inputSizeClass="col-md-8"
|
143
158
|
rows={8}
|
144
159
|
/>
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import Immutable from 'seamless-immutable';
|
1
2
|
import { STATUS } from 'foremanReact/constants';
|
2
3
|
import { deepPropsToCamelCase } from 'foremanReact/common/helpers';
|
3
4
|
import {
|
@@ -31,14 +32,12 @@ export const selectWebhookTemplates = state => {
|
|
31
32
|
if (selectTemplatesHasError(state) || selectTemplatesIsLoading(state))
|
32
33
|
return [];
|
33
34
|
|
34
|
-
return selectWebhookFormTemplatesResponse(state).results;
|
35
|
+
return Immutable.asMutable(selectWebhookFormTemplatesResponse(state).results);
|
35
36
|
};
|
36
37
|
|
37
38
|
// Webhook events selectors
|
38
39
|
const selectWebhookFormEventsResponse = state =>
|
39
|
-
|
40
|
-
selectAPIResponse(state, WEBHOOK_EVENTS_API_REQUEST_KEY)
|
41
|
-
);
|
40
|
+
selectAPIResponse(state, WEBHOOK_EVENTS_API_REQUEST_KEY);
|
42
41
|
|
43
42
|
const selectWebhookFormEventsStatus = state =>
|
44
43
|
selectAPIStatus(state, WEBHOOK_EVENTS_API_REQUEST_KEY);
|
@@ -54,5 +53,5 @@ export const selectEventsIsLoading = state => {
|
|
54
53
|
export const selectWebhookEvents = state => {
|
55
54
|
if (selectEventsHasError(state) || selectEventsIsLoading(state)) return [];
|
56
55
|
|
57
|
-
return selectWebhookFormEventsResponse(state);
|
56
|
+
return Immutable.asMutable(selectWebhookFormEventsResponse(state));
|
58
57
|
};
|
@@ -0,0 +1,100 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { useDispatch } from 'react-redux';
|
3
|
+
import PropTypes from 'prop-types';
|
4
|
+
|
5
|
+
import { sprintf, translate as __ } from 'foremanReact/common/I18n';
|
6
|
+
import ForemanModal from 'foremanReact/components/ForemanModal';
|
7
|
+
import ForemanForm from 'foremanReact/components/common/forms/ForemanForm';
|
8
|
+
import { foremanUrl } from 'foremanReact/common/helpers';
|
9
|
+
import { submitForm } from 'foremanReact/redux/actions/common/forms';
|
10
|
+
import { useForemanModal } from 'foremanReact/components/ForemanModal/ForemanModalHooks';
|
11
|
+
|
12
|
+
import ForemanFormikField from '../../../Webhooks/Components/WebhookForm/Components/ForemanFormikField';
|
13
|
+
|
14
|
+
import {
|
15
|
+
WEBHOOK_TEST_MODAL_ID,
|
16
|
+
WEBHOOKS_API_PLAIN_PATH,
|
17
|
+
} from '../../constants';
|
18
|
+
|
19
|
+
import './WebhookModal.scss';
|
20
|
+
|
21
|
+
const WebhookTestModal = ({ toTest }) => {
|
22
|
+
const dispatch = useDispatch();
|
23
|
+
|
24
|
+
const { id, name } = toTest;
|
25
|
+
const { setModalClosed: setTestModalClosed } = useForemanModal({
|
26
|
+
id: WEBHOOK_TEST_MODAL_ID,
|
27
|
+
});
|
28
|
+
const initialTestValues = {
|
29
|
+
payload: '',
|
30
|
+
};
|
31
|
+
const errorToast = error =>
|
32
|
+
sprintf(
|
33
|
+
__('Webhook test failed: %s'),
|
34
|
+
error?.response?.data?.error?.message
|
35
|
+
);
|
36
|
+
|
37
|
+
const handleSubmit = (values, actions) => {
|
38
|
+
dispatch(
|
39
|
+
submitForm({
|
40
|
+
url: foremanUrl(`${WEBHOOKS_API_PLAIN_PATH}/${id}/test`),
|
41
|
+
values: { ...values, controller: 'webhooks' },
|
42
|
+
item: 'WebhookTest',
|
43
|
+
message: sprintf(__('Webhook %s test was successful'), name),
|
44
|
+
method: 'post',
|
45
|
+
successCallback: () => actions.setSubmitting(false),
|
46
|
+
actions,
|
47
|
+
errorToast,
|
48
|
+
handleError: () => actions.setSubmitting(false),
|
49
|
+
})
|
50
|
+
);
|
51
|
+
};
|
52
|
+
|
53
|
+
return (
|
54
|
+
<ForemanModal
|
55
|
+
id={WEBHOOK_TEST_MODAL_ID}
|
56
|
+
title={`${__('Test')} ${name}`}
|
57
|
+
backdrop="static"
|
58
|
+
enforceFocus
|
59
|
+
className="webhooks-modal"
|
60
|
+
>
|
61
|
+
<p>
|
62
|
+
{sprintf(
|
63
|
+
__(
|
64
|
+
'You are about to test %s webhook.' +
|
65
|
+
'\n' +
|
66
|
+
'Please, note that this will not contain actual information or render the attached template.' +
|
67
|
+
'\n' +
|
68
|
+
'You can specify below a custom payload to test the webhook with.'
|
69
|
+
),
|
70
|
+
name
|
71
|
+
)}
|
72
|
+
</p>
|
73
|
+
<ForemanForm
|
74
|
+
onSubmit={handleSubmit}
|
75
|
+
initialValues={initialTestValues}
|
76
|
+
onCancel={setTestModalClosed}
|
77
|
+
>
|
78
|
+
<ForemanFormikField
|
79
|
+
name="payload"
|
80
|
+
type="textarea"
|
81
|
+
label={__('Payload')}
|
82
|
+
labelHelp={__('Will be sent as is')}
|
83
|
+
placeholder="{ id: 1, name: test }"
|
84
|
+
inputSizeClass="col-md-8"
|
85
|
+
rows={8}
|
86
|
+
/>
|
87
|
+
</ForemanForm>
|
88
|
+
</ForemanModal>
|
89
|
+
);
|
90
|
+
};
|
91
|
+
|
92
|
+
WebhookTestModal.propTypes = {
|
93
|
+
toTest: PropTypes.object,
|
94
|
+
};
|
95
|
+
|
96
|
+
WebhookTestModal.defaultProps = {
|
97
|
+
toTest: {},
|
98
|
+
};
|
99
|
+
|
100
|
+
export default WebhookTestModal;
|
@@ -0,0 +1,40 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
4
|
+
import { ActionButtons } from 'foremanReact/components/common/ActionButtons/ActionButtons';
|
5
|
+
|
6
|
+
export const ActionButton = ({ id, name, canDelete, webhookActions }) => {
|
7
|
+
const buttons = [];
|
8
|
+
if (canDelete) {
|
9
|
+
buttons.push({
|
10
|
+
title: __('Delete'),
|
11
|
+
action: {
|
12
|
+
onClick: () => webhookActions.deleteWebhook(id, name),
|
13
|
+
id: `webhook-delete-button-${id}`,
|
14
|
+
},
|
15
|
+
});
|
16
|
+
}
|
17
|
+
buttons.push({
|
18
|
+
title: __('Test webhook'),
|
19
|
+
action: {
|
20
|
+
onClick: () => webhookActions.testWebhook(id, name),
|
21
|
+
id: `webhook-test-button-${id}`,
|
22
|
+
},
|
23
|
+
});
|
24
|
+
|
25
|
+
return <ActionButtons buttons={buttons} />;
|
26
|
+
};
|
27
|
+
|
28
|
+
ActionButton.propTypes = {
|
29
|
+
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
|
30
|
+
name: PropTypes.string.isRequired,
|
31
|
+
canDelete: PropTypes.bool,
|
32
|
+
webhookActions: PropTypes.shape({
|
33
|
+
deleteWebhook: PropTypes.func,
|
34
|
+
testWebhook: PropTypes.func,
|
35
|
+
}).isRequired,
|
36
|
+
};
|
37
|
+
|
38
|
+
ActionButton.defaultProps = {
|
39
|
+
canDelete: false,
|
40
|
+
};
|