choria-mcorpc-support 2.24.3 → 2.25.2
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/mcollective/agent/aaa_signer.ddl +41 -0
- data/lib/mcollective/agent/aaa_signer.json +46 -0
- data/lib/mcollective/agent/choria_provision.ddl +297 -0
- data/lib/mcollective/agent/choria_provision.json +323 -0
- data/lib/mcollective/agent/choria_registry.ddl +65 -0
- data/lib/mcollective/agent/choria_registry.json +74 -0
- data/lib/mcollective/agent/choria_util.ddl +24 -4
- data/lib/mcollective/agent/choria_util.json +24 -24
- data/lib/mcollective/agent/rpcutil.ddl +242 -183
- data/lib/mcollective/agent/rpcutil.json +53 -56
- data/lib/mcollective/agent/scout.ddl +4 -4
- data/lib/mcollective/agent/scout.json +1 -1
- data/lib/mcollective/discovery/delegate.rb +6 -2
- data/lib/mcollective/util/tasks_support.rb +12 -3
- metadata +14 -2
@@ -0,0 +1,323 @@
|
|
1
|
+
{
|
2
|
+
"$schema": "https://choria.io/schemas/mcorpc/ddl/v1/agent.json",
|
3
|
+
"metadata": {
|
4
|
+
"name": "choria_provision",
|
5
|
+
"description": "Choria Provisioner",
|
6
|
+
"author": "R.I.Pienaar <rip@devco.net>",
|
7
|
+
"license": "Apache-2.0",
|
8
|
+
"version": "0.24.0",
|
9
|
+
"url": "https://choria.io",
|
10
|
+
"timeout": 20
|
11
|
+
},
|
12
|
+
"actions": [
|
13
|
+
{
|
14
|
+
"action": "configure",
|
15
|
+
"input": {
|
16
|
+
"token": {
|
17
|
+
"prompt": "Token",
|
18
|
+
"description": "Authentication token to pass to the server",
|
19
|
+
"type": "string",
|
20
|
+
"default": "",
|
21
|
+
"optional": true,
|
22
|
+
"validation": ".",
|
23
|
+
"maxlength": 128
|
24
|
+
},
|
25
|
+
"config": {
|
26
|
+
"prompt": "Configuration",
|
27
|
+
"description": "The configuration to apply to this node",
|
28
|
+
"type": "string",
|
29
|
+
"default": null,
|
30
|
+
"optional": false,
|
31
|
+
"validation": "^{.+}$",
|
32
|
+
"maxlength": 2048
|
33
|
+
},
|
34
|
+
"certificate": {
|
35
|
+
"prompt": "Certificate",
|
36
|
+
"description": "PEM text block for the certificate",
|
37
|
+
"type": "string",
|
38
|
+
"default": null,
|
39
|
+
"optional": true,
|
40
|
+
"validation": "^-----BEGIN CERTIFICATE-----",
|
41
|
+
"maxlength": 10240
|
42
|
+
},
|
43
|
+
"ca": {
|
44
|
+
"prompt": "CA Bundle",
|
45
|
+
"description": "PEM text block for the CA",
|
46
|
+
"type": "string",
|
47
|
+
"default": null,
|
48
|
+
"optional": true,
|
49
|
+
"validation": "^-----BEGIN CERTIFICATE-----",
|
50
|
+
"maxlength": 20480
|
51
|
+
},
|
52
|
+
"ssldir": {
|
53
|
+
"prompt": "SSL Dir",
|
54
|
+
"description": "Directory for storing the certificate in",
|
55
|
+
"type": "string",
|
56
|
+
"default": null,
|
57
|
+
"optional": true,
|
58
|
+
"validation": ".",
|
59
|
+
"maxlength": 500
|
60
|
+
},
|
61
|
+
"key": {
|
62
|
+
"prompt": "PEM text block for the private key",
|
63
|
+
"type": "string",
|
64
|
+
"default": null,
|
65
|
+
"optional": true,
|
66
|
+
"validation": "-----BEGIN RSA PRIVATE KEY-----",
|
67
|
+
"maxlength": 10240
|
68
|
+
},
|
69
|
+
"ecdh_public": {
|
70
|
+
"prompt": "ECDH Public Key",
|
71
|
+
"description": "Required when sending a private key",
|
72
|
+
"type": "string",
|
73
|
+
"default": "",
|
74
|
+
"optional": true,
|
75
|
+
"maxlength": 64,
|
76
|
+
"validation": "."
|
77
|
+
},
|
78
|
+
"action_policies": {
|
79
|
+
"prompt": "Action Policy Documents",
|
80
|
+
"description": "Map of Action Policy documents indexed by file name",
|
81
|
+
"type": "hash",
|
82
|
+
"default": {},
|
83
|
+
"optional": true
|
84
|
+
},
|
85
|
+
"opa_policies": {
|
86
|
+
"prompt": "Open Policy Agent Policy Documents",
|
87
|
+
"description": "Map of Open Policy Agent Policy documents indexed by file name",
|
88
|
+
"type": "hash",
|
89
|
+
"default": {},
|
90
|
+
"optional": true
|
91
|
+
}
|
92
|
+
|
93
|
+
},
|
94
|
+
"output": {
|
95
|
+
"message": {
|
96
|
+
"description": "Status message from the Provisioner",
|
97
|
+
"display_as": "Message",
|
98
|
+
"type": "string",
|
99
|
+
"default": null
|
100
|
+
}
|
101
|
+
},
|
102
|
+
"display": "failed",
|
103
|
+
"description": "Configure the Choria Server"
|
104
|
+
},
|
105
|
+
{
|
106
|
+
"action": "gencsr",
|
107
|
+
"input": {
|
108
|
+
"token": {
|
109
|
+
"prompt": "Token",
|
110
|
+
"description": "Authentication token to pass to the server",
|
111
|
+
"type": "string",
|
112
|
+
"default": "",
|
113
|
+
"optional": true,
|
114
|
+
"validation": ".",
|
115
|
+
"maxlength": 128
|
116
|
+
},
|
117
|
+
"cn": {
|
118
|
+
"prompt": "Common Name",
|
119
|
+
"description": "The certificate Common Name to place in the CSR",
|
120
|
+
"type": "string",
|
121
|
+
"default": null,
|
122
|
+
"optional": true,
|
123
|
+
"validation": "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]).)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])$",
|
124
|
+
"maxlength": 80
|
125
|
+
},
|
126
|
+
"C": {
|
127
|
+
"prompt": "Country",
|
128
|
+
"description": "Country Code",
|
129
|
+
"type": "string",
|
130
|
+
"default": null,
|
131
|
+
"optional": true,
|
132
|
+
"validation": "^[A-Z]{2}$",
|
133
|
+
"maxlength": 2
|
134
|
+
},
|
135
|
+
"L": {
|
136
|
+
"prompt": "Locality",
|
137
|
+
"description": "Locality or municipality (such as city or town name)",
|
138
|
+
"type": "string",
|
139
|
+
"default": null,
|
140
|
+
"optional": true,
|
141
|
+
"validation": "^[\\w\\s-]+$",
|
142
|
+
"maxlength": 50
|
143
|
+
},
|
144
|
+
"O": {
|
145
|
+
"prompt": "Organization",
|
146
|
+
"description": "Organization",
|
147
|
+
"type": "string",
|
148
|
+
"default": null,
|
149
|
+
"optional": true,
|
150
|
+
"validation": "^[\\w\\s-]+$",
|
151
|
+
"maxlength": 50
|
152
|
+
},
|
153
|
+
"OU": {
|
154
|
+
"prompt": "Organizational Unit",
|
155
|
+
"description": "Organizational Unit",
|
156
|
+
"type": "string",
|
157
|
+
"default": null,
|
158
|
+
"optional": true,
|
159
|
+
"validation": "^[\\w\\s-]+$",
|
160
|
+
"maxlength": 50
|
161
|
+
},
|
162
|
+
"ST": {
|
163
|
+
"prompt": "State",
|
164
|
+
"description": "State",
|
165
|
+
"type": "string",
|
166
|
+
"default": null,
|
167
|
+
"optional": true,
|
168
|
+
"validation": "^[\\w\\s-]+$",
|
169
|
+
"maxlength": 50
|
170
|
+
}
|
171
|
+
},
|
172
|
+
"output": {
|
173
|
+
"csr": {
|
174
|
+
"description": "PEM text block for the CSR",
|
175
|
+
"display_as": "CSR",
|
176
|
+
"type": "string",
|
177
|
+
"default": null
|
178
|
+
},
|
179
|
+
"public_key": {
|
180
|
+
"description": "PEM text block of the public key that made the CSR",
|
181
|
+
"display_as": "Public Key",
|
182
|
+
"type": "string",
|
183
|
+
"default": null
|
184
|
+
},
|
185
|
+
"ssldir": {
|
186
|
+
"description": "SSL directory as determined by the server",
|
187
|
+
"display_as": "SSL Dir",
|
188
|
+
"type": "string",
|
189
|
+
"default": null
|
190
|
+
}
|
191
|
+
},
|
192
|
+
"display": "always",
|
193
|
+
"description": "Request a CSR from the Choria Server"
|
194
|
+
},
|
195
|
+
{
|
196
|
+
"action": "release_update",
|
197
|
+
"input": {
|
198
|
+
"token": {
|
199
|
+
"prompt": "Token",
|
200
|
+
"description": "Authentication token to pass to the server",
|
201
|
+
"type": "string",
|
202
|
+
"default": "",
|
203
|
+
"optional": true,
|
204
|
+
"validation": ".",
|
205
|
+
"maxlength": 128
|
206
|
+
},
|
207
|
+
"repository": {
|
208
|
+
"prompt": "Repository URL",
|
209
|
+
"description": "HTTP(S) server hosting the update repository",
|
210
|
+
"type": "string",
|
211
|
+
"default": "",
|
212
|
+
"optional": false,
|
213
|
+
"validation": "^http(s*)://",
|
214
|
+
"maxlength": 512
|
215
|
+
},
|
216
|
+
"version": {
|
217
|
+
"prompt": "Version to update to",
|
218
|
+
"description": "Package version to update to",
|
219
|
+
"type": "string",
|
220
|
+
"default": "",
|
221
|
+
"optional": false,
|
222
|
+
"validation": ".+",
|
223
|
+
"maxlength": 32
|
224
|
+
}
|
225
|
+
},
|
226
|
+
"output": {
|
227
|
+
"message": {
|
228
|
+
"description": "Status message from the Provisioner",
|
229
|
+
"display_as": "Message",
|
230
|
+
"type": "string",
|
231
|
+
"default": null
|
232
|
+
}
|
233
|
+
},
|
234
|
+
"display": "always",
|
235
|
+
"description": "Performs an in-place binary update and restarts Choria"
|
236
|
+
},
|
237
|
+
{
|
238
|
+
"action": "jwt",
|
239
|
+
"input": {
|
240
|
+
"token": {
|
241
|
+
"prompt": "Token",
|
242
|
+
"description": "Authentication token to pass to the server",
|
243
|
+
"type": "string",
|
244
|
+
"default": "",
|
245
|
+
"optional": true,
|
246
|
+
"validation": ".",
|
247
|
+
"maxlength": 128
|
248
|
+
}
|
249
|
+
},
|
250
|
+
"output": {
|
251
|
+
"jwt": {
|
252
|
+
"description": "The contents of the JWT token",
|
253
|
+
"display_as": "JWT Token",
|
254
|
+
"type": "string",
|
255
|
+
"default": ""
|
256
|
+
},
|
257
|
+
"ecdh_public": {
|
258
|
+
"description": "The ECDH public key for calculating shared secrets",
|
259
|
+
"display_as": "ECDH Public Key",
|
260
|
+
"type": "string",
|
261
|
+
"default": ""
|
262
|
+
}
|
263
|
+
},
|
264
|
+
"display": "always",
|
265
|
+
"description": "Re-enable provision mode in a running Choria Server"
|
266
|
+
},
|
267
|
+
{
|
268
|
+
"action": "reprovision",
|
269
|
+
"input": {
|
270
|
+
"token": {
|
271
|
+
"prompt": "Token",
|
272
|
+
"description": "Authentication token to pass to the server",
|
273
|
+
"type": "string",
|
274
|
+
"default": "",
|
275
|
+
"optional": true,
|
276
|
+
"validation": ".",
|
277
|
+
"maxlength": 128
|
278
|
+
}
|
279
|
+
},
|
280
|
+
"output": {
|
281
|
+
"message": {
|
282
|
+
"description": "Status message from the Provisioner",
|
283
|
+
"display_as": "Message",
|
284
|
+
"type": "string",
|
285
|
+
"default": null
|
286
|
+
}
|
287
|
+
},
|
288
|
+
"display": "always",
|
289
|
+
"description": "Reenable provision mode in a running Choria Server"
|
290
|
+
},
|
291
|
+
{
|
292
|
+
"action": "restart",
|
293
|
+
"input": {
|
294
|
+
"token": {
|
295
|
+
"prompt": "Token",
|
296
|
+
"description": "Authentication token to pass to the server",
|
297
|
+
"type": "string",
|
298
|
+
"default": "",
|
299
|
+
"optional": true,
|
300
|
+
"validation": ".",
|
301
|
+
"maxlength": 128
|
302
|
+
},
|
303
|
+
"splay": {
|
304
|
+
"prompt": "Splay time",
|
305
|
+
"description": "The configuration to apply to this node",
|
306
|
+
"type": "number",
|
307
|
+
"default": null,
|
308
|
+
"optional": true
|
309
|
+
}
|
310
|
+
},
|
311
|
+
"output": {
|
312
|
+
"message": {
|
313
|
+
"description": "Status message from the Provisioner",
|
314
|
+
"display_as": "Message",
|
315
|
+
"type": "string",
|
316
|
+
"default": null
|
317
|
+
}
|
318
|
+
},
|
319
|
+
"display": "failed",
|
320
|
+
"description": "Restart the Choria Server"
|
321
|
+
}
|
322
|
+
]
|
323
|
+
}
|
@@ -0,0 +1,65 @@
|
|
1
|
+
metadata :name => "choria_registry",
|
2
|
+
:description => "Choria Registry Service",
|
3
|
+
:author => "rip@devco.net <rip@devco.net>",
|
4
|
+
:license => "Apache-2.0",
|
5
|
+
:version => "0.24.0",
|
6
|
+
:url => "https://choria.io",
|
7
|
+
:provider => "golang",
|
8
|
+
:service => true,
|
9
|
+
:timeout => 2
|
10
|
+
|
11
|
+
|
12
|
+
action "ddl", :description => "Retrieve the DDL for a specific plugin" do
|
13
|
+
display :always
|
14
|
+
|
15
|
+
input :format,
|
16
|
+
:prompt => "Plugin Format",
|
17
|
+
:description => "The result format the plugin should be retrieved in",
|
18
|
+
:type => :list,
|
19
|
+
:default => "json",
|
20
|
+
:list => ["ddl", "json"],
|
21
|
+
:optional => true
|
22
|
+
|
23
|
+
|
24
|
+
input :name,
|
25
|
+
:prompt => "Plugin Name",
|
26
|
+
:description => "The name of the plugin",
|
27
|
+
:type => :string,
|
28
|
+
:validation => :shellsafe,
|
29
|
+
:maxlength => 64,
|
30
|
+
:optional => false
|
31
|
+
|
32
|
+
|
33
|
+
input :plugin_type,
|
34
|
+
:prompt => "Plugin Type",
|
35
|
+
:description => "The type of plugin",
|
36
|
+
:type => :list,
|
37
|
+
:default => "agent",
|
38
|
+
:list => ["agent"],
|
39
|
+
:optional => false
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
output :ddl,
|
45
|
+
:description => "The plugin DDL in the requested format",
|
46
|
+
:type => "string",
|
47
|
+
:display_as => "DDL"
|
48
|
+
|
49
|
+
output :name,
|
50
|
+
:description => "The name of the plugin",
|
51
|
+
:type => "string",
|
52
|
+
:display_as => "Name"
|
53
|
+
|
54
|
+
output :plugin_type,
|
55
|
+
:description => "The type of plugin",
|
56
|
+
:type => "string",
|
57
|
+
:display_as => "Type"
|
58
|
+
|
59
|
+
output :version,
|
60
|
+
:description => "The version of the plugin",
|
61
|
+
:type => "string",
|
62
|
+
:display_as => "Version"
|
63
|
+
|
64
|
+
end
|
65
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
{
|
2
|
+
"$schema": "https://choria.io/schemas/mcorpc/ddl/v1/agent.json",
|
3
|
+
"metadata": {
|
4
|
+
"license": "Apache-2.0",
|
5
|
+
"author": "rip@devco.net \u003crip@devco.net\u003e",
|
6
|
+
"timeout": 2,
|
7
|
+
"name": "choria_registry",
|
8
|
+
"version": "0.24.0",
|
9
|
+
"url": "https://choria.io",
|
10
|
+
"description": "Choria Registry Service",
|
11
|
+
"provider": "golang",
|
12
|
+
"service": true
|
13
|
+
},
|
14
|
+
"actions": [
|
15
|
+
{
|
16
|
+
"action": "ddl",
|
17
|
+
"input": {
|
18
|
+
"format": {
|
19
|
+
"prompt": "Plugin Format",
|
20
|
+
"description": "The result format the plugin should be retrieved in",
|
21
|
+
"type": "list",
|
22
|
+
"default": "json",
|
23
|
+
"optional": true,
|
24
|
+
"list": [
|
25
|
+
"ddl",
|
26
|
+
"json"
|
27
|
+
]
|
28
|
+
},
|
29
|
+
"name": {
|
30
|
+
"prompt": "Plugin Name",
|
31
|
+
"description": "The name of the plugin",
|
32
|
+
"type": "string",
|
33
|
+
"optional": false,
|
34
|
+
"validation": "shellsafe",
|
35
|
+
"maxlength": 64
|
36
|
+
},
|
37
|
+
"plugin_type": {
|
38
|
+
"prompt": "Plugin Type",
|
39
|
+
"description": "The type of plugin",
|
40
|
+
"type": "list",
|
41
|
+
"default": "agent",
|
42
|
+
"optional": false,
|
43
|
+
"list": [
|
44
|
+
"agent"
|
45
|
+
]
|
46
|
+
}
|
47
|
+
},
|
48
|
+
"output": {
|
49
|
+
"ddl": {
|
50
|
+
"description": "The plugin DDL in the requested format",
|
51
|
+
"display_as": "DDL",
|
52
|
+
"type": "string"
|
53
|
+
},
|
54
|
+
"name": {
|
55
|
+
"description": "The name of the plugin",
|
56
|
+
"display_as": "Name",
|
57
|
+
"type": "string"
|
58
|
+
},
|
59
|
+
"plugin_type": {
|
60
|
+
"description": "The type of plugin",
|
61
|
+
"display_as": "Type",
|
62
|
+
"type": "string"
|
63
|
+
},
|
64
|
+
"version": {
|
65
|
+
"description": "The version of the plugin",
|
66
|
+
"display_as": "Version",
|
67
|
+
"type": "string"
|
68
|
+
}
|
69
|
+
},
|
70
|
+
"display": "always",
|
71
|
+
"description": "Retrieve the DDL for a specific plugin"
|
72
|
+
}
|
73
|
+
]
|
74
|
+
}
|
@@ -2,7 +2,7 @@ metadata :name => "choria_util",
|
|
2
2
|
:description => "Choria Utilities",
|
3
3
|
:author => "R.I.Pienaar <rip@devco.net>",
|
4
4
|
:license => "Apache-2.0",
|
5
|
-
:version => "0.
|
5
|
+
:version => "0.24.0",
|
6
6
|
:url => "https://choria.io",
|
7
7
|
:timeout => 2
|
8
8
|
|
@@ -14,66 +14,82 @@ action "info", :description => "Choria related information from the running Daem
|
|
14
14
|
|
15
15
|
output :choria_version,
|
16
16
|
:description => "Choria version",
|
17
|
+
:type => "string",
|
17
18
|
:display_as => "Choria Version"
|
18
19
|
|
19
20
|
output :client_flavour,
|
20
|
-
:description => "Middleware client
|
21
|
+
:description => "Middleware client library flavour",
|
22
|
+
:type => "string",
|
21
23
|
:display_as => "Middleware Client Flavour"
|
22
24
|
|
23
25
|
output :client_options,
|
24
|
-
:description => "Active Middleware client
|
26
|
+
:description => "Active Middleware client options",
|
27
|
+
:type => "hash",
|
25
28
|
:display_as => "Middleware Client Options"
|
26
29
|
|
27
30
|
output :client_stats,
|
28
|
-
:description => "Middleware client
|
31
|
+
:description => "Middleware client statistics",
|
32
|
+
:type => "hash",
|
29
33
|
:display_as => "Middleware Client Stats"
|
30
34
|
|
31
35
|
output :client_version,
|
32
36
|
:description => "Middleware client library version",
|
37
|
+
:type => "string",
|
33
38
|
:display_as => "Middleware Client Library Version"
|
34
39
|
|
35
40
|
output :connected_server,
|
36
41
|
:description => "Connected middleware server",
|
42
|
+
:type => "string",
|
37
43
|
:display_as => "Connected Broker"
|
38
44
|
|
39
45
|
output :connector,
|
40
46
|
:description => "Connector plugin",
|
47
|
+
:type => "string",
|
41
48
|
:display_as => "Connector"
|
42
49
|
|
43
50
|
output :connector_tls,
|
44
51
|
:description => "If the connector is running with TLS security enabled",
|
52
|
+
:type => "boolean",
|
45
53
|
:display_as => "Connector TLS"
|
46
54
|
|
47
55
|
output :facter_command,
|
48
56
|
:description => "Command used for Facter",
|
57
|
+
:type => "string",
|
49
58
|
:display_as => "Facter"
|
50
59
|
|
51
60
|
output :facter_domain,
|
52
61
|
:description => "Facter domain",
|
62
|
+
:type => "string",
|
53
63
|
:display_as => "Facter Domain"
|
54
64
|
|
55
65
|
output :middleware_servers,
|
56
66
|
:description => "Middleware Servers configured or discovered",
|
67
|
+
:type => "array",
|
57
68
|
:display_as => "Middleware"
|
58
69
|
|
59
70
|
output :path,
|
60
71
|
:description => "Active OS PATH",
|
72
|
+
:type => "string",
|
61
73
|
:display_as => "Path"
|
62
74
|
|
63
75
|
output :secure_protocol,
|
64
76
|
:description => "If the protocol is running with PKI security enabled",
|
77
|
+
:type => "boolean",
|
65
78
|
:display_as => "Protocol Secure"
|
66
79
|
|
67
80
|
output :security,
|
68
81
|
:description => "Security Provider plugin",
|
82
|
+
:type => "string",
|
69
83
|
:display_as => "Security Provider"
|
70
84
|
|
71
85
|
output :srv_domain,
|
72
86
|
:description => "Configured SRV domain",
|
87
|
+
:type => "string",
|
73
88
|
:display_as => "SRV Domain"
|
74
89
|
|
75
90
|
output :using_srv,
|
76
91
|
:description => "Indicates if SRV records are considered",
|
92
|
+
:type => "boolean",
|
77
93
|
:display_as => "SRV Used"
|
78
94
|
|
79
95
|
summarize do
|
@@ -178,14 +194,17 @@ action "machine_states", :description => "States of the hosted Choria Autonomous
|
|
178
194
|
|
179
195
|
output :machine_ids,
|
180
196
|
:description => "List of running machine IDs",
|
197
|
+
:type => "array",
|
181
198
|
:display_as => "Machine IDs"
|
182
199
|
|
183
200
|
output :machine_names,
|
184
201
|
:description => "List of running machine names",
|
202
|
+
:type => "array",
|
185
203
|
:display_as => "Machine Names"
|
186
204
|
|
187
205
|
output :states,
|
188
206
|
:description => "Hash map of machine statusses indexed by machine ID",
|
207
|
+
:type => "hash",
|
189
208
|
:display_as => "Machine States"
|
190
209
|
|
191
210
|
summarize do
|
@@ -245,6 +264,7 @@ action "machine_transition", :description => "Attempts to force a transition in
|
|
245
264
|
|
246
265
|
output :success,
|
247
266
|
:description => "Indicates if the transition was successfully accepted",
|
267
|
+
:type => "boolean",
|
248
268
|
:display_as => "Accepted"
|
249
269
|
|
250
270
|
end
|