@spinnaker/docker 2025.3.0 → 2025.4.0-rc1

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.
package/dist/index.js CHANGED
@@ -1,1570 +1,2 @@
1
- import { REST, RetryService, AccountService, ValidationMessage, HelpField, Tooltip, SETTINGS, Registry, BakeExecutionLabel, AuthenticationService, BakeryReader, TetheredSelect, Spinner } from '@spinnaker/core';
2
- import _, { groupBy, reduce, uniq, trim, get } from 'lodash';
3
- import React from 'react';
4
- import Select from 'react-select';
5
- import { module } from 'angular';
6
- import UIROUTER_ANGULARJS from '@uirouter/angularjs';
7
- import { $q } from 'ngimport';
8
- import { Subject, from } from 'rxjs';
9
- import { debounceTime, switchMap } from 'rxjs/operators';
10
-
11
- class DockerImageReader {
12
- static getImage(imageName, region, credentials) {
13
- return REST("/images").path(credentials, region, imageName).query({ provider: "docker" }).get().then((results) => results && results.length ? results[0] : null).catch(() => null);
14
- }
15
- static findImages(params) {
16
- return RetryService.buildRetrySequence(() => REST("/images/find").query(params).get(), (results) => results.length > 0, 10, 1e3).then((results) => results).catch(() => []);
17
- }
18
- static findTags(params) {
19
- return RetryService.buildRetrySequence(() => REST("/images/tags").query(params).get(), (results) => results.length > 0, 10, 1e3).then((results) => results).catch(() => []);
20
- }
21
- }
22
- class DockerChartImageReader {
23
- static getImage(imageName, region, credentials) {
24
- return REST("/charts").path(credentials, region, imageName).query({ provider: "docker" }).get().then((results) => results && results.length ? results[0] : null).catch(() => null);
25
- }
26
- static findImages(params) {
27
- return RetryService.buildRetrySequence(() => REST("/charts/find").query(params).get(), (results) => results.length > 0, 10, 1e3).then((results) => results).catch(() => []);
28
- }
29
- static findTags(params) {
30
- return RetryService.buildRetrySequence(() => REST("/charts/tags").query(params).get(), (results) => results.length > 0, 10, 1e3).then((results) => results).catch(() => []);
31
- }
32
- }
33
-
34
- class DockerImageUtils {
35
- static splitImageId(imageId = "") {
36
- let imageParts;
37
- if (imageId.includes("@")) {
38
- imageParts = imageId.split("@");
39
- } else {
40
- imageParts = imageId.split(":");
41
- }
42
- const repository = imageParts[0];
43
- const repositoryParts = repository.split("/");
44
- const organization = repositoryParts.slice(0, -1).join("/");
45
- const lookup = imageParts.length > 1 ? imageParts.slice(1).join(":") : "";
46
- let tag;
47
- let digest;
48
- if (lookup) {
49
- if (lookup.startsWith("sha256:")) {
50
- digest = lookup;
51
- } else {
52
- tag = lookup;
53
- }
54
- }
55
- return { organization, repository, digest, tag };
56
- }
57
- static generateImageId(parts) {
58
- if (!parts.repository || !(parts.digest || parts.tag)) {
59
- return void 0;
60
- }
61
- let imageId;
62
- if (parts.digest) {
63
- imageId = `${parts.repository}@${parts.digest}`;
64
- } else {
65
- imageId = `${parts.repository}:${parts.tag}`;
66
- }
67
- return imageId;
68
- }
69
- }
70
-
71
- const imageFields$1 = ["organization", "repository", "tag", "digest"];
72
- const defineOptions$1 = [
73
- { label: "Manually", value: true },
74
- { label: "Select from list", value: false }
75
- ];
76
- class DockerImageAndTagSelector extends React.Component {
77
- constructor(props) {
78
- super(props);
79
- this.unmounted = false;
80
- this.cachedValues = {};
81
- this.handleRefreshImages = () => {
82
- this.refreshImages(this.props);
83
- };
84
- this.lookupTypeChanged = (o) => {
85
- const newType = o.value;
86
- const oldType = this.state.lookupType;
87
- const oldValue = this.props[oldType];
88
- const cachedValue = this.cachedValues[newType];
89
- this.valueChanged(oldType, void 0);
90
- if (this.cachedValues[newType]) {
91
- this.valueChanged(newType, cachedValue);
92
- }
93
- this.setState({ lookupType: newType });
94
- this.cachedValues[oldType] = oldValue;
95
- };
96
- this.showManualInput = (defineManually) => {
97
- if (!defineManually) {
98
- const newFields = DockerImageUtils.splitImageId(this.props.imageId || "");
99
- this.props.onChange(newFields);
100
- if (this.state.switchedManualWarning) {
101
- this.setState({ switchedManualWarning: void 0, missingFields: void 0 });
102
- }
103
- }
104
- this.setState({ defineManually });
105
- };
106
- const accountOptions = props.account ? [{ label: props.account, value: props.account }] : [];
107
- const organizationOptions = props.organization && props.organization.length ? [{ label: props.organization, value: props.organization }] : [];
108
- const repositoryOptions = props.repository && props.repository.length ? [{ label: props.repository, value: props.repository }] : [];
109
- const tagOptions = props.tag && props.tag.length ? [{ label: props.tag, value: props.tag }] : [];
110
- const parsedImageId = DockerImageUtils.splitImageId(props.imageId);
111
- const defineManually = props.allowManualDefinition && Boolean(props.imageId && props.imageId.includes("${"));
112
- this.state = {
113
- accountOptions,
114
- switchedManualWarning: void 0,
115
- imagesLoaded: false,
116
- imagesLoading: false,
117
- organizationOptions,
118
- repositoryOptions,
119
- defineManually,
120
- tagOptions,
121
- lookupType: props.digest || parsedImageId.digest ? "digest" : "tag"
122
- };
123
- }
124
- getAccountMap(images) {
125
- const groupedImages = groupBy(images.filter((image) => image.account), "account");
126
- return reduce(groupedImages, (acc, image, key) => {
127
- acc[key] = uniq(image.map((i) => `${i.repository.split("/").slice(0, -1).join("/")}`));
128
- return acc;
129
- }, {});
130
- }
131
- getRegistryMap(images) {
132
- return images.reduce((m, image) => {
133
- m[image.account] = image.registry;
134
- return m;
135
- }, {});
136
- }
137
- getOrganizationMap(images) {
138
- const extractGroupByKey = (image) => `${image.account}/${image.repository.split("/").slice(0, -1).join("/")}`;
139
- const groupedImages = groupBy(images.filter((image) => image.repository), extractGroupByKey);
140
- return reduce(groupedImages, (acc, image, key) => {
141
- acc[key] = uniq(image.map((i) => i.repository));
142
- return acc;
143
- }, {});
144
- }
145
- getRepositoryMap(images) {
146
- const groupedImages = groupBy(images.filter((image) => image.account), "repository");
147
- return reduce(groupedImages, (acc, image, key) => {
148
- acc[key] = uniq(image.map((i) => i.tag));
149
- return acc;
150
- }, {});
151
- }
152
- getOrganizationsList(accountMap) {
153
- return accountMap ? accountMap[this.props.showRegistry ? this.props.account : this.props.registry] || [] : [];
154
- }
155
- getRepositoryList(organizationMap, organization, registry) {
156
- if (organizationMap) {
157
- const key = `${this.props.showRegistry ? this.props.account : registry}/${organization || ""}`;
158
- return organizationMap[key] || [];
159
- }
160
- return [];
161
- }
162
- getTags(tag, repositoryMap, repository) {
163
- let tags = [];
164
- if (this.props.specifyTagByRegex) {
165
- if (tag && trim(tag) === "") {
166
- tag = void 0;
167
- }
168
- } else {
169
- if (repositoryMap) {
170
- tags = repositoryMap[repository] || [];
171
- if (!tags.includes(tag) && tag && !tag.includes("${")) {
172
- tag = void 0;
173
- }
174
- }
175
- }
176
- return { tag, tags };
177
- }
178
- componentWillReceiveProps(nextProps) {
179
- if (!this.images || ["account", "showRegistry"].some((key) => this.props[key] !== nextProps[key])) {
180
- this.refreshImages(nextProps);
181
- } else if (["organization", "registry", "repository"].some((key) => this.props[key] !== nextProps[key])) {
182
- this.updateThings(nextProps);
183
- }
184
- if (nextProps.imageId && nextProps.imageId.includes("${")) {
185
- this.setState({ defineManually: true });
186
- }
187
- }
188
- componentWillUnmount() {
189
- this.unmounted = true;
190
- }
191
- synchronizeChanges(values, registry) {
192
- const { organization, repository, tag, digest } = values;
193
- if (this.props.onChange) {
194
- const imageId = DockerImageUtils.generateImageId({ organization, repository, tag, digest });
195
- const changes = {};
196
- if (tag !== this.props.tag) {
197
- changes.tag = tag;
198
- }
199
- if (imageId !== this.props.imageId) {
200
- changes.imageId = imageId;
201
- }
202
- if (organization !== this.props.organization) {
203
- changes.organization = organization;
204
- }
205
- if (registry !== this.props.registry) {
206
- changes.registry = registry;
207
- }
208
- if (repository !== this.props.repository) {
209
- changes.repository = repository;
210
- }
211
- if (digest !== this.props.digest) {
212
- changes.digest = digest;
213
- }
214
- if (Object.keys(changes).length > 0) {
215
- this.props.onChange(changes);
216
- }
217
- }
218
- }
219
- updateThings(props, allowAutoSwitchToManualEntry = false) {
220
- if (!this.repositoryMap || this.unmounted) {
221
- return;
222
- }
223
- const { imageId, specifyTagByRegex } = props;
224
- let { organization, registry, repository } = props;
225
- if (props.showRegistry) {
226
- registry = this.registryMap[props.account];
227
- }
228
- const organizationFound = !organization || this.organizations.includes(organization) || organization.includes("${");
229
- if (!organizationFound) {
230
- organization = "";
231
- }
232
- const repositories = this.getRepositoryList(this.organizationMap, organization, registry);
233
- const repositoryFound = !repository || repository.includes("${") || repositories.includes(repository);
234
- if (!repositoryFound) {
235
- repository = "";
236
- }
237
- const { tag, tags } = this.getTags(props.tag, this.repositoryMap, repository);
238
- const tagFound = tag === props.tag || specifyTagByRegex;
239
- const newState = {
240
- accountOptions: this.newAccounts.sort().map((a) => ({ label: a, value: a })),
241
- organizationOptions: this.organizations.filter((o) => o).sort().map((o) => ({ label: o, value: o })),
242
- imagesLoaded: true,
243
- repositoryOptions: repositories.sort().map((r) => ({ label: r, value: r })),
244
- tagOptions: tags.sort().map((t) => ({ label: t, value: t }))
245
- };
246
- if (imageId && (!this.state.imagesLoaded || allowAutoSwitchToManualEntry) && (!organizationFound || !repositoryFound || !tagFound)) {
247
- newState.defineManually = true;
248
- const missingFields = [];
249
- if (!organizationFound) {
250
- missingFields.push("organization");
251
- }
252
- if (!repositoryFound) {
253
- missingFields.push("image");
254
- }
255
- if (!tagFound) {
256
- missingFields.push("tag");
257
- }
258
- newState.missingFields = missingFields;
259
- newState.switchedManualWarning = `Could not find ${missingFields.join(" or ")}, switched to manual entry`;
260
- } else if (!imageId || !imageId.includes("${")) {
261
- this.synchronizeChanges(this.state.defineManually ? DockerImageUtils.splitImageId(imageId) : { organization, repository, tag, digest: this.props.digest }, registry);
262
- }
263
- this.setState(newState);
264
- }
265
- initializeImages(props) {
266
- if (this.state.imagesLoading) {
267
- return;
268
- }
269
- const { showRegistry, account, registry } = props;
270
- const imageConfig = {
271
- provider: "dockerRegistry",
272
- account: showRegistry ? account : registry
273
- };
274
- this.setState({ imagesLoading: true });
275
- DockerImageReader.findImages(imageConfig).then((images) => {
276
- this.images = images;
277
- this.registryMap = this.getRegistryMap(this.images);
278
- this.accountMap = this.getAccountMap(this.images);
279
- this.newAccounts = this.accounts || Object.keys(this.accountMap);
280
- this.organizationMap = this.getOrganizationMap(this.images);
281
- this.repositoryMap = this.getRepositoryMap(this.images);
282
- this.organizations = this.getOrganizationsList(this.accountMap);
283
- this.updateThings(props, true);
284
- }).finally(() => {
285
- if (!this.unmounted) {
286
- this.setState({ imagesLoading: false });
287
- }
288
- });
289
- }
290
- refreshImages(props) {
291
- this.initializeImages(props);
292
- }
293
- initializeAccounts(props) {
294
- let { account } = props;
295
- AccountService.listAccounts("dockerRegistry").then((allAccounts) => {
296
- const accounts = allAccounts.map((a) => a.name);
297
- if (this.props.showRegistry && !account) {
298
- account = accounts[0];
299
- }
300
- this.accounts = accounts;
301
- this.refreshImages({ ...props, ...{ account } });
302
- });
303
- }
304
- isNew() {
305
- const { account, organization, registry, repository, tag } = this.props;
306
- return !account && !organization && !registry && !repository && !tag;
307
- }
308
- componentDidMount() {
309
- if (!this.props.deferInitialization && (this.props.registry || this.isNew())) {
310
- this.initializeAccounts(this.props);
311
- }
312
- }
313
- valueChanged(name, value) {
314
- const changes = { [name]: value };
315
- if (imageFields$1.some((n) => n === name)) {
316
- const { organization, repository, tag, digest } = this.props;
317
- const imageParts = { ...{ organization, repository, tag, digest }, ...changes };
318
- const imageId = DockerImageUtils.generateImageId(imageParts);
319
- changes.imageId = imageId;
320
- }
321
- this.props.onChange && this.props.onChange(changes);
322
- }
323
- render() {
324
- const {
325
- account,
326
- allowManualDefinition,
327
- digest,
328
- imageId,
329
- organization,
330
- repository,
331
- showDigest,
332
- showRegistry,
333
- specifyTagByRegex,
334
- tag
335
- } = this.props;
336
- const {
337
- accountOptions,
338
- switchedManualWarning,
339
- missingFields,
340
- imagesLoading,
341
- lookupType,
342
- organizationOptions,
343
- repositoryOptions,
344
- defineManually,
345
- tagOptions
346
- } = this.state;
347
- const parsedImageId = DockerImageUtils.splitImageId(imageId);
348
- const manualInputToggle = /* @__PURE__ */ React.createElement("div", {
349
- className: "sp-formItem groupHeader"
350
- }, /* @__PURE__ */ React.createElement("div", {
351
- className: "sp-formItem__left"
352
- }, /* @__PURE__ */ React.createElement("div", {
353
- className: "sp-formLabel"
354
- }, "Define Image ID"), /* @__PURE__ */ React.createElement("div", {
355
- className: "sp-formActions sp-formActions--mobile"
356
- }, /* @__PURE__ */ React.createElement("span", {
357
- className: "action"
358
- }))), /* @__PURE__ */ React.createElement("div", {
359
- className: "sp-formItem__right"
360
- }, /* @__PURE__ */ React.createElement("div", {
361
- className: "sp-form"
362
- }, /* @__PURE__ */ React.createElement("span", {
363
- className: "field"
364
- }, /* @__PURE__ */ React.createElement(Select, {
365
- value: defineManually,
366
- disabled: imagesLoading || !allowManualDefinition,
367
- onChange: (o) => this.showManualInput(o.value),
368
- options: defineOptions$1,
369
- clearable: false
370
- })))));
371
- const warning = switchedManualWarning ? /* @__PURE__ */ React.createElement("div", {
372
- className: "sp-formItem"
373
- }, /* @__PURE__ */ React.createElement("div", {
374
- className: "sp-formItem__left"
375
- }), /* @__PURE__ */ React.createElement("div", {
376
- className: "sp-formItem__right"
377
- }, /* @__PURE__ */ React.createElement(ValidationMessage, {
378
- type: "warning",
379
- message: /* @__PURE__ */ React.createElement(React.Fragment, null, switchedManualWarning, (missingFields || []).map((f) => /* @__PURE__ */ React.createElement("div", {
380
- key: f
381
- }, /* @__PURE__ */ React.createElement(HelpField, {
382
- expand: true,
383
- id: `pipeline.config.docker.trigger.missing.${f}`
384
- }))))
385
- }))) : null;
386
- if (defineManually) {
387
- return /* @__PURE__ */ React.createElement("div", {
388
- className: "sp-formGroup"
389
- }, manualInputToggle, /* @__PURE__ */ React.createElement("div", {
390
- className: "sp-formItem"
391
- }, /* @__PURE__ */ React.createElement("div", {
392
- className: "sp-formItem__left"
393
- }, /* @__PURE__ */ React.createElement("div", {
394
- className: "sp-formLabel"
395
- }, "Image ID"), /* @__PURE__ */ React.createElement("div", {
396
- className: "sp-formActions sp-formActions--mobile"
397
- }, /* @__PURE__ */ React.createElement("span", {
398
- className: "action"
399
- }))), /* @__PURE__ */ React.createElement("div", {
400
- className: "sp-formItem__right"
401
- }, /* @__PURE__ */ React.createElement("div", {
402
- className: "sp-form"
403
- }, /* @__PURE__ */ React.createElement("span", {
404
- className: "field"
405
- }, /* @__PURE__ */ React.createElement("input", {
406
- className: "form-control input-sm",
407
- value: imageId || "",
408
- onChange: (e) => this.valueChanged("imageId", e.target.value)
409
- }))))), warning);
410
- }
411
- const Registry = showRegistry ? /* @__PURE__ */ React.createElement("div", {
412
- className: "sp-formItem"
413
- }, /* @__PURE__ */ React.createElement("div", {
414
- className: "sp-formItem__left"
415
- }, /* @__PURE__ */ React.createElement("div", {
416
- className: "sp-formLabel"
417
- }, "Registry Name")), /* @__PURE__ */ React.createElement("div", {
418
- className: "sp-formItem__right"
419
- }, /* @__PURE__ */ React.createElement("div", {
420
- className: "sp-form"
421
- }, /* @__PURE__ */ React.createElement("span", {
422
- className: "field"
423
- }, /* @__PURE__ */ React.createElement(Select, {
424
- value: account,
425
- disabled: imagesLoading,
426
- onChange: (o) => this.valueChanged("account", o ? o.value : ""),
427
- options: accountOptions,
428
- isLoading: imagesLoading
429
- })), /* @__PURE__ */ React.createElement("span", {
430
- className: "sp-formActions sp-formActions--web"
431
- }, /* @__PURE__ */ React.createElement("span", {
432
- className: "action"
433
- }, /* @__PURE__ */ React.createElement(Tooltip, {
434
- value: imagesLoading ? "Images refreshing" : "Refresh images list"
435
- }, /* @__PURE__ */ React.createElement("i", {
436
- className: `fa icon-button-refresh-arrows ${imagesLoading ? "fa-spin" : ""}`,
437
- onClick: this.handleRefreshImages
438
- }))))))) : null;
439
- const Organization = /* @__PURE__ */ React.createElement("div", {
440
- className: "sp-formItem"
441
- }, /* @__PURE__ */ React.createElement("div", {
442
- className: "sp-formItem__left"
443
- }, /* @__PURE__ */ React.createElement("div", {
444
- className: "sp-formLabel"
445
- }, "Organization")), /* @__PURE__ */ React.createElement("div", {
446
- className: "sp-formItem__right"
447
- }, /* @__PURE__ */ React.createElement("div", {
448
- className: "sp-form"
449
- }, /* @__PURE__ */ React.createElement("span", {
450
- className: "field"
451
- }, organization.includes("${") ? /* @__PURE__ */ React.createElement("input", {
452
- disabled: imagesLoading,
453
- className: "form-control input-sm",
454
- value: organization || "",
455
- onChange: (e) => this.valueChanged("organization", e.target.value)
456
- }) : /* @__PURE__ */ React.createElement(Select, {
457
- value: organization || "",
458
- disabled: imagesLoading,
459
- onChange: (o) => this.valueChanged("organization", o && o.value || ""),
460
- placeholder: "No organization",
461
- options: organizationOptions,
462
- isLoading: imagesLoading
463
- })))));
464
- const Image = /* @__PURE__ */ React.createElement("div", {
465
- className: "sp-formItem"
466
- }, /* @__PURE__ */ React.createElement("div", {
467
- className: "sp-formItem__left"
468
- }, /* @__PURE__ */ React.createElement("div", {
469
- className: "sp-formLabel"
470
- }, "Image")), /* @__PURE__ */ React.createElement("div", {
471
- className: "sp-formItem__right"
472
- }, /* @__PURE__ */ React.createElement("div", {
473
- className: "sp-form"
474
- }, /* @__PURE__ */ React.createElement("span", {
475
- className: "field"
476
- }, repository.includes("${") ? /* @__PURE__ */ React.createElement("input", {
477
- className: "form-control input-sm",
478
- disabled: imagesLoading,
479
- value: repository || "",
480
- onChange: (e) => this.valueChanged("repository", e.target.value)
481
- }) : /* @__PURE__ */ React.createElement(Select, {
482
- value: repository || "",
483
- disabled: imagesLoading,
484
- onChange: (o) => this.valueChanged("repository", o && o.value || ""),
485
- options: repositoryOptions,
486
- required: true,
487
- isLoading: imagesLoading
488
- })))));
489
- const Tag = lookupType === "tag" ? specifyTagByRegex ? /* @__PURE__ */ React.createElement("div", {
490
- className: "sp-formItem"
491
- }, /* @__PURE__ */ React.createElement("div", {
492
- className: "sp-formItem__left"
493
- }, /* @__PURE__ */ React.createElement("div", {
494
- className: "sp-formLabel"
495
- }, "Tag")), /* @__PURE__ */ React.createElement("div", {
496
- className: "sp-formItem__right"
497
- }, /* @__PURE__ */ React.createElement("div", {
498
- className: "sp-form"
499
- }, /* @__PURE__ */ React.createElement("span", {
500
- className: "field"
501
- }, /* @__PURE__ */ React.createElement("input", {
502
- type: "text",
503
- className: "form-control input-sm",
504
- value: tag || "",
505
- disabled: imagesLoading || !repository,
506
- onChange: (e) => this.valueChanged("tag", e.target.value)
507
- }))), /* @__PURE__ */ React.createElement(HelpField, {
508
- id: "pipeline.config.docker.trigger.tag",
509
- expand: true
510
- }))) : /* @__PURE__ */ React.createElement("div", {
511
- className: "sp-formItem"
512
- }, /* @__PURE__ */ React.createElement("div", {
513
- className: "sp-formItem__left"
514
- }, /* @__PURE__ */ React.createElement("div", {
515
- className: "sp-formLabel"
516
- }, "Tag")), /* @__PURE__ */ React.createElement("div", {
517
- className: "sp-formItem__right"
518
- }, /* @__PURE__ */ React.createElement("div", {
519
- className: "sp-form"
520
- }, /* @__PURE__ */ React.createElement("span", {
521
- className: "field"
522
- }, tag && tag.includes("${") ? /* @__PURE__ */ React.createElement("input", {
523
- className: "form-control input-sm",
524
- disabled: imagesLoading,
525
- value: tag || "",
526
- onChange: (e) => this.valueChanged("tag", e.target.value),
527
- required: true
528
- }) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Select, {
529
- value: tag || "",
530
- disabled: imagesLoading || !repository,
531
- isLoading: imagesLoading,
532
- onChange: (o) => this.valueChanged("tag", o ? o.value : void 0),
533
- options: tagOptions,
534
- placeholder: "No tag",
535
- required: true
536
- }), /* @__PURE__ */ React.createElement(HelpField, {
537
- id: "pipeline.config.docker.trigger.tag.additionalInfo",
538
- expand: true
539
- })))))) : null;
540
- const Digest = lookupType === "digest" ? /* @__PURE__ */ React.createElement("div", {
541
- className: "sp-formItem"
542
- }, /* @__PURE__ */ React.createElement("div", {
543
- className: "sp-formItem__left"
544
- }, /* @__PURE__ */ React.createElement("div", {
545
- className: "sp-formLabel"
546
- }, "Digest ", /* @__PURE__ */ React.createElement(HelpField, {
547
- id: "pipeline.config.docker.trigger.digest"
548
- }))), /* @__PURE__ */ React.createElement("div", {
549
- className: "sp-formItem__right"
550
- }, /* @__PURE__ */ React.createElement("div", {
551
- className: "sp-form"
552
- }, /* @__PURE__ */ React.createElement("span", {
553
- className: "field"
554
- }, /* @__PURE__ */ React.createElement("input", {
555
- className: "form-control input-sm",
556
- placeholder: "sha256:abc123",
557
- value: digest || parsedImageId.digest || "",
558
- onChange: (e) => this.valueChanged("digest", e.target.value),
559
- required: true
560
- }))))) : null;
561
- const LookupTypeSelector = showDigest ? /* @__PURE__ */ React.createElement("div", {
562
- className: "sp-formItem"
563
- }, /* @__PURE__ */ React.createElement("div", {
564
- className: "sp-formItem__left"
565
- }, /* @__PURE__ */ React.createElement("div", {
566
- className: "sp-formLabel"
567
- }, "Type")), /* @__PURE__ */ React.createElement("div", {
568
- className: "sp-formItem__right"
569
- }, /* @__PURE__ */ React.createElement("div", {
570
- className: "sp-form"
571
- }, /* @__PURE__ */ React.createElement("span", {
572
- className: "field"
573
- }, /* @__PURE__ */ React.createElement(Select, {
574
- clearable: false,
575
- value: lookupType,
576
- options: [
577
- { value: "digest", label: "Digest" },
578
- { value: "tag", label: "Tag" }
579
- ],
580
- onChange: this.lookupTypeChanged
581
- }))))) : null;
582
- return /* @__PURE__ */ React.createElement("div", {
583
- className: "sp-formGroup"
584
- }, manualInputToggle, Registry, Organization, Image, LookupTypeSelector, Digest, Tag);
585
- }
586
- }
587
- DockerImageAndTagSelector.defaultProps = {
588
- organization: "",
589
- registry: "",
590
- repository: "",
591
- showDigest: true,
592
- allowManualDefinition: true
593
- };
594
-
595
- const DOCKER_PIPELINE_STAGES_BAKE_BAKEEXECUTIONDETAILS_CONTROLLER = "spinnaker.docker.pipeline.stage.bake.executionDetails.controller";
596
- module(DOCKER_PIPELINE_STAGES_BAKE_BAKEEXECUTIONDETAILS_CONTROLLER, [UIROUTER_ANGULARJS]).controller("dockerBakeExecutionDetailsCtrl", [
597
- "$scope",
598
- "$stateParams",
599
- "executionDetailsSectionService",
600
- "$interpolate",
601
- function($scope, $stateParams, executionDetailsSectionService, $interpolate) {
602
- $scope.configSections = ["bakeConfig", "taskStatus"];
603
- const initialized = () => {
604
- $scope.detailsSection = $stateParams.details;
605
- $scope.provider = $scope.stage.context.cloudProviderType || "docker";
606
- $scope.bakeryDetailUrl = $interpolate($scope.roscoMode && SETTINGS.roscoDetailUrl ? SETTINGS.roscoDetailUrl : SETTINGS.bakeryDetailUrl);
607
- };
608
- const initialize = () => executionDetailsSectionService.synchronizeSection($scope.configSections, initialized);
609
- initialize();
610
- $scope.$on("$stateChangeSuccess", initialize);
611
- }
612
- ]);
613
-
614
- const DOCKER_PIPELINE_STAGES_BAKE_DOCKERBAKESTAGE = "spinnaker.docker.pipeline.stage.bakeStage";
615
- module(DOCKER_PIPELINE_STAGES_BAKE_DOCKERBAKESTAGE, [DOCKER_PIPELINE_STAGES_BAKE_BAKEEXECUTIONDETAILS_CONTROLLER]).config(function() {
616
- Registry.pipeline.registerStage({
617
- provides: "bake",
618
- cloudProvider: "docker",
619
- label: "Bake",
620
- description: "Bakes an image",
621
- templateUrl: "docker/src/pipeline/stages/bake/bakeStage.html",
622
- executionDetailsUrl: "docker/src/pipeline/stages/bake/bakeExecutionDetails.html",
623
- executionLabelComponent: BakeExecutionLabel,
624
- extraLabelLines: (stage) => {
625
- return stage.masterStage.context.allPreviouslyBaked || stage.masterStage.context.somePreviouslyBaked ? 1 : 0;
626
- },
627
- supportsCustomTimeout: true,
628
- validators: [{ type: "requiredField", fieldName: "package" }],
629
- restartable: true
630
- });
631
- }).controller("dockerBakeStageCtrl", [
632
- "$scope",
633
- "$q",
634
- function($scope, $q) {
635
- const stage = $scope.stage;
636
- stage.region = "global";
637
- if (!$scope.stage.user) {
638
- $scope.stage.user = AuthenticationService.getAuthenticatedUser().name;
639
- }
640
- $scope.viewState = {
641
- loading: true
642
- };
643
- function initialize() {
644
- $scope.viewState.providerSelected = true;
645
- $q.all([BakeryReader.getBaseOsOptions("docker"), BakeryReader.getBaseLabelOptions()]).then(function([
646
- baseOsOptions,
647
- baseLabelOptions
648
- ]) {
649
- $scope.baseOsOptions = baseOsOptions.baseImages;
650
- $scope.baseLabelOptions = baseLabelOptions;
651
- if (!$scope.stage.baseOs && $scope.baseOsOptions && $scope.baseOsOptions.length) {
652
- $scope.stage.baseOs = $scope.baseOsOptions[0].id;
653
- }
654
- if (!$scope.stage.baseLabel && $scope.baseLabelOptions && $scope.baseLabelOptions.length) {
655
- $scope.stage.baseLabel = $scope.baseLabelOptions[0];
656
- }
657
- $scope.viewState.loading = false;
658
- });
659
- }
660
- function deleteEmptyProperties() {
661
- _.forOwn($scope.stage, function(val, key) {
662
- if (val === "") {
663
- delete $scope.stage[key];
664
- }
665
- });
666
- }
667
- $scope.$watch("stage", deleteEmptyProperties, true);
668
- initialize();
669
- }
670
- ]);
671
- window.angular.module("ng").run(["$templateCache", function(templateCache) {
672
- templateCache.put("docker/src/pipeline/stages/bake/bakeStage.html", `<div ng-controller="dockerBakeStageCtrl as bakeStageCtrl">
673
- <stage-config-field label="Package" help-key="pipeline.config.bake.package">
674
- <input type="text" class="form-control input-sm" ng-model="stage.package" />
675
- </stage-config-field>
676
- <stage-config-field label="Organization" help-key="pipeline.config.docker.bake.organization">
677
- <input type="text" class="form-control input-sm" ng-model="stage.organization" />
678
- </stage-config-field>
679
- <stage-config-field label="Image Name" help-key="pipeline.config.docker.bake.targetImage">
680
- <input type="text" class="form-control input-sm" ng-model="stage.ami_name" />
681
- </stage-config-field>
682
- <stage-config-field label="Image tag" help-key="pipeline.config.docker.bake.targetImageTag">
683
- <input type="text" class="form-control input-sm" ng-model="stage.extendedAttributes['docker_target_image_tag']" />
684
- </stage-config-field>
685
- <stage-config-field label="Base OS">
686
- <bake-stage-choose-os model="stage.baseOs" base-os-options="baseOsOptions"></bake-stage-choose-os>
687
- </stage-config-field>
688
-
689
- <stage-config-field label="Base Label">
690
- <label class="radio-inline" ng-repeat="baseLabel in baseLabelOptions">
691
- <input type="radio" ng-model="stage.baseLabel" ng-value="baseLabel" />
692
- {{baseLabel}}
693
- </label>
694
- </stage-config-field>
695
- <stage-config-field label="Rebake">
696
- <div class="checkbox" style="margin-bottom: 0">
697
- <label>
698
- <input type="checkbox" ng-model="stage.rebake" />
699
- Rebake image without regard to the status of any existing bake
700
- </label>
701
- </div>
702
- </stage-config-field>
703
- </div>
704
- `);
705
- }]);
706
- window.angular.module("ng").run(["$templateCache", function(templateCache) {
707
- templateCache.put("docker/src/pipeline/stages/bake/bakeExecutionDetails.html", `<div ng-controller="dockerBakeExecutionDetailsCtrl">
708
- <execution-details-section-nav sections="configSections"></execution-details-section-nav>
709
- <div class="step-section-details" ng-if="detailsSection === 'bakeConfig'">
710
- <div class="row">
711
- <div class="col-md-6">
712
- <dl class="dl-narrow dl-horizontal">
713
- <dt if-multiple-providers>Provider</dt>
714
- <dd if-multiple-providers>Docker</dd>
715
- <dt>Organization</dt>
716
- <dd>{{stage.context.organization}}</dd>
717
- <dt>Image Name</dt>
718
- <dd>{{stage.context.ami_name}}</dd>
719
- <dt>Image Tag</dt>
720
- <dd>{{stage.context.extendedAttributes['docker_target_image_tag']}}</dd>
721
- <dt>Image</dt>
722
- <dd>{{stage.context.ami}}</dd>
723
- </dl>
724
- </div>
725
- <div class="col-md-6">
726
- <dl class="dl-narrow dl-horizontal">
727
- <dt>Base OS</dt>
728
- <dd>{{stage.context.baseOs}}</dd>
729
- <dt>Region</dt>
730
- <dd>{{stage.context.region}}</dd>
731
- <dt>Package</dt>
732
- <dd>{{stage.context.package}}</dd>
733
- <dt>Label</dt>
734
- <dd>{{stage.context.baseLabel}}</dd>
735
- </dl>
736
- </div>
737
- </div>
738
- <stage-failure-message stage="stage" message="stage.failureMessage"></stage-failure-message>
739
-
740
- <div class="row" ng-if="stage.context.region && stage.context.status.resourceId">
741
- <div class="col-md-12">
742
- <div class="alert alert-{{stage.isFailed ? 'danger' : 'info'}}">
743
- <a target="_blank" href="{{ bakeryDetailUrl(stage) }}"> View Bakery Details </a>
744
- </div>
745
- </div>
746
- </div>
747
- </div>
748
- <div class="step-section-details" ng-if="detailsSection === 'taskStatus'">
749
- <div class="row">
750
- <execution-step-details item="stage"></execution-step-details>
751
- </div>
752
- </div>
753
- </div>
754
- `);
755
- }]);
756
-
757
- const imageFields = ["organization", "repository", "tag", "digest"];
758
- const defineOptions = [
759
- { label: "Manually", value: true },
760
- { label: "Select from list", value: false }
761
- ];
762
- class DockerChartAndTagSelector extends React.Component {
763
- constructor(props) {
764
- super(props);
765
- this.unmounted = false;
766
- this.cachedValues = {};
767
- this.handleRefreshImages = () => {
768
- this.refreshImages(this.props);
769
- };
770
- this.lookupTypeChanged = (o) => {
771
- const newType = o.value;
772
- const oldType = this.state.lookupType;
773
- const oldValue = this.props[oldType];
774
- const cachedValue = this.cachedValues[newType];
775
- this.valueChanged(oldType, void 0);
776
- if (this.cachedValues[newType]) {
777
- this.valueChanged(newType, cachedValue);
778
- }
779
- this.setState({ lookupType: newType });
780
- this.cachedValues[oldType] = oldValue;
781
- };
782
- this.showManualInput = (defineManually) => {
783
- if (!defineManually) {
784
- const newFields = DockerImageUtils.splitImageId(this.props.imageId || "");
785
- this.props.onChange(newFields);
786
- if (this.state.switchedManualWarning) {
787
- this.setState({ switchedManualWarning: void 0, missingFields: void 0 });
788
- }
789
- }
790
- this.setState({ defineManually });
791
- };
792
- const accountOptions = props.account ? [{ label: props.account, value: props.account }] : [];
793
- const organizationOptions = props.organization && props.organization.length ? [{ label: props.organization, value: props.organization }] : [];
794
- const repositoryOptions = props.repository && props.repository.length ? [{ label: props.repository, value: props.repository }] : [];
795
- const tagOptions = props.tag && props.tag.length ? [{ label: props.tag, value: props.tag }] : [];
796
- const parsedImageId = DockerImageUtils.splitImageId(props.imageId);
797
- const defineManually = props.allowManualDefinition && Boolean(props.imageId && props.imageId.includes("${"));
798
- this.state = {
799
- accountOptions,
800
- switchedManualWarning: void 0,
801
- imagesLoaded: false,
802
- imagesLoading: false,
803
- organizationOptions,
804
- repositoryOptions,
805
- defineManually,
806
- tagOptions,
807
- lookupType: props.digest || parsedImageId.digest ? "digest" : "tag"
808
- };
809
- }
810
- getAccountMap(images) {
811
- const groupedImages = groupBy(images.filter((image) => image.account), "account");
812
- return reduce(groupedImages, (acc, image, key) => {
813
- acc[key] = uniq(image.map((i) => `${i.repository.split("/").slice(0, -1).join("/")}`));
814
- return acc;
815
- }, {});
816
- }
817
- getRegistryMap(images) {
818
- return images.reduce((m, image) => {
819
- m[image.account] = image.registry;
820
- return m;
821
- }, {});
822
- }
823
- getOrganizationMap(images) {
824
- const extractGroupByKey = (image) => `${image.account}/${image.repository.split("/").slice(0, -1).join("/")}`;
825
- const groupedImages = groupBy(images.filter((image) => image.repository), extractGroupByKey);
826
- return reduce(groupedImages, (acc, image, key) => {
827
- acc[key] = uniq(image.map((i) => i.repository));
828
- return acc;
829
- }, {});
830
- }
831
- getRepositoryMap(images) {
832
- const groupedImages = groupBy(images.filter((image) => image.account), "repository");
833
- return reduce(groupedImages, (acc, image, key) => {
834
- acc[key] = uniq(image.map((i) => i.tag));
835
- return acc;
836
- }, {});
837
- }
838
- getOrganizationsList(accountMap) {
839
- return accountMap ? accountMap[this.props.showRegistry ? this.props.account : this.props.registry] || [] : [];
840
- }
841
- getRepositoryList(organizationMap, organization, registry) {
842
- if (organizationMap) {
843
- const key = `${this.props.showRegistry ? this.props.account : registry}/${organization || ""}`;
844
- return organizationMap[key] || [];
845
- }
846
- return [];
847
- }
848
- getTags(tag, repositoryMap, repository) {
849
- let tags = [];
850
- if (this.props.specifyTagByRegex) {
851
- if (tag && trim(tag) === "") {
852
- tag = void 0;
853
- }
854
- } else {
855
- if (repositoryMap) {
856
- tags = repositoryMap[repository] || [];
857
- if (!tags.includes(tag) && tag && !tag.includes("${")) {
858
- tag = void 0;
859
- }
860
- }
861
- }
862
- return { tag, tags };
863
- }
864
- componentWillReceiveProps(nextProps) {
865
- if (!this.images || ["account", "showRegistry"].some((key) => this.props[key] !== nextProps[key])) {
866
- this.refreshImages(nextProps);
867
- } else if (["organization", "registry", "repository"].some((key) => this.props[key] !== nextProps[key])) {
868
- this.updateThings(nextProps);
869
- }
870
- if (nextProps.imageId && nextProps.imageId.includes("${")) {
871
- this.setState({ defineManually: true });
872
- }
873
- }
874
- componentWillUnmount() {
875
- this.unmounted = true;
876
- }
877
- synchronizeChanges(values, registry) {
878
- const { organization, repository, tag, digest } = values;
879
- if (this.props.onChange) {
880
- const imageId = DockerImageUtils.generateImageId({ organization, repository, tag, digest });
881
- const changes = {};
882
- if (tag !== this.props.tag) {
883
- changes.tag = tag;
884
- }
885
- if (imageId !== this.props.imageId) {
886
- changes.imageId = imageId;
887
- }
888
- if (organization !== this.props.organization) {
889
- changes.organization = organization;
890
- }
891
- if (registry !== this.props.registry) {
892
- changes.registry = registry;
893
- }
894
- if (repository !== this.props.repository) {
895
- changes.repository = repository;
896
- }
897
- if (digest !== this.props.digest) {
898
- changes.digest = digest;
899
- }
900
- if (Object.keys(changes).length > 0) {
901
- this.props.onChange(changes);
902
- }
903
- }
904
- }
905
- updateThings(props, allowAutoSwitchToManualEntry = false) {
906
- if (!this.repositoryMap || this.unmounted) {
907
- return;
908
- }
909
- const { imageId, specifyTagByRegex } = props;
910
- let { organization, registry, repository } = props;
911
- if (props.showRegistry) {
912
- registry = this.registryMap[props.account];
913
- }
914
- const organizationFound = !organization || this.organizations.includes(organization) || organization.includes("${");
915
- if (!organizationFound) {
916
- organization = "";
917
- }
918
- const repositories = this.getRepositoryList(this.organizationMap, organization, registry);
919
- const repositoryFound = !repository || repository.includes("${") || repositories.includes(repository);
920
- if (!repositoryFound) {
921
- repository = "";
922
- }
923
- const { tag, tags } = this.getTags(props.tag, this.repositoryMap, repository);
924
- const tagFound = tag === props.tag || specifyTagByRegex;
925
- const newState = {
926
- accountOptions: this.newAccounts.sort().map((a) => ({ label: a, value: a })),
927
- organizationOptions: this.organizations.filter((o) => o).sort().map((o) => ({ label: o, value: o })),
928
- imagesLoaded: true,
929
- repositoryOptions: repositories.sort().map((r) => ({ label: r, value: r })),
930
- tagOptions: tags.sort().map((t) => ({ label: t, value: t }))
931
- };
932
- if (imageId && (!this.state.imagesLoaded || allowAutoSwitchToManualEntry) && (!organizationFound || !repositoryFound || !tagFound)) {
933
- newState.defineManually = true;
934
- const missingFields = [];
935
- if (!organizationFound) {
936
- missingFields.push("organization");
937
- }
938
- if (!repositoryFound) {
939
- missingFields.push("image");
940
- }
941
- if (!tagFound) {
942
- missingFields.push("tag");
943
- }
944
- newState.missingFields = missingFields;
945
- newState.switchedManualWarning = `Could not find ${missingFields.join(" or ")}, switched to manual entry`;
946
- } else if (!imageId || !imageId.includes("${")) {
947
- this.synchronizeChanges(this.state.defineManually ? DockerImageUtils.splitImageId(imageId) : { organization, repository, tag, digest: this.props.digest }, registry);
948
- }
949
- this.setState(newState);
950
- }
951
- initializeImages(props) {
952
- if (this.state.imagesLoading) {
953
- return;
954
- }
955
- const { showRegistry, account, registry } = props;
956
- const imageConfig = {
957
- provider: "dockerRegistry",
958
- account: showRegistry ? account : registry
959
- };
960
- this.setState({ imagesLoading: true });
961
- DockerChartImageReader.findImages(imageConfig).then((images) => {
962
- this.images = images;
963
- this.registryMap = this.getRegistryMap(this.images);
964
- this.accountMap = this.getAccountMap(this.images);
965
- this.newAccounts = this.accounts || Object.keys(this.accountMap);
966
- this.organizationMap = this.getOrganizationMap(this.images);
967
- this.repositoryMap = this.getRepositoryMap(this.images);
968
- this.organizations = this.getOrganizationsList(this.accountMap);
969
- this.updateThings(props, true);
970
- }).finally(() => {
971
- if (!this.unmounted) {
972
- this.setState({ imagesLoading: false });
973
- }
974
- });
975
- }
976
- refreshImages(props) {
977
- this.initializeImages(props);
978
- }
979
- initializeAccounts(props) {
980
- let { account } = props;
981
- AccountService.listAccounts("dockerRegistry").then((allAccounts) => {
982
- const accounts = allAccounts.map((a) => a.name);
983
- if (this.props.showRegistry && !account) {
984
- account = accounts[0];
985
- }
986
- this.accounts = accounts;
987
- this.refreshImages({ ...props, ...{ account } });
988
- });
989
- }
990
- isNew() {
991
- const { account, organization, registry, repository, tag } = this.props;
992
- return !account && !organization && !registry && !repository && !tag;
993
- }
994
- componentDidMount() {
995
- if (!this.props.deferInitialization && (this.props.registry || this.isNew())) {
996
- this.initializeAccounts(this.props);
997
- }
998
- }
999
- valueChanged(name, value) {
1000
- const changes = { [name]: value };
1001
- if (imageFields.some((n) => n === name)) {
1002
- const { organization, repository, tag, digest } = this.props;
1003
- const imageParts = { ...{ organization, repository, tag, digest }, ...changes };
1004
- const imageId = DockerImageUtils.generateImageId(imageParts);
1005
- changes.imageId = imageId;
1006
- }
1007
- this.props.onChange && this.props.onChange(changes);
1008
- }
1009
- render() {
1010
- const {
1011
- account,
1012
- allowManualDefinition,
1013
- digest,
1014
- imageId,
1015
- organization,
1016
- repository,
1017
- showDigest,
1018
- showRegistry,
1019
- specifyTagByRegex,
1020
- tag
1021
- } = this.props;
1022
- const {
1023
- accountOptions,
1024
- switchedManualWarning,
1025
- missingFields,
1026
- imagesLoading,
1027
- lookupType,
1028
- organizationOptions,
1029
- repositoryOptions,
1030
- defineManually,
1031
- tagOptions
1032
- } = this.state;
1033
- const parsedImageId = DockerImageUtils.splitImageId(imageId);
1034
- const manualInputToggle = /* @__PURE__ */ React.createElement("div", {
1035
- className: "sp-formItem groupHeader"
1036
- }, /* @__PURE__ */ React.createElement("div", {
1037
- className: "sp-formItem__left"
1038
- }, /* @__PURE__ */ React.createElement("div", {
1039
- className: "sp-formLabel"
1040
- }, "Define Image ID"), /* @__PURE__ */ React.createElement("div", {
1041
- className: "sp-formActions sp-formActions--mobile"
1042
- }, /* @__PURE__ */ React.createElement("span", {
1043
- className: "action"
1044
- }))), /* @__PURE__ */ React.createElement("div", {
1045
- className: "sp-formItem__right"
1046
- }, /* @__PURE__ */ React.createElement("div", {
1047
- className: "sp-form"
1048
- }, /* @__PURE__ */ React.createElement("span", {
1049
- className: "field"
1050
- }, /* @__PURE__ */ React.createElement(Select, {
1051
- value: defineManually,
1052
- disabled: imagesLoading || !allowManualDefinition,
1053
- onChange: (o) => this.showManualInput(o.value),
1054
- options: defineOptions,
1055
- clearable: false
1056
- })))));
1057
- const warning = switchedManualWarning ? /* @__PURE__ */ React.createElement("div", {
1058
- className: "sp-formItem"
1059
- }, /* @__PURE__ */ React.createElement("div", {
1060
- className: "sp-formItem__left"
1061
- }), /* @__PURE__ */ React.createElement("div", {
1062
- className: "sp-formItem__right"
1063
- }, /* @__PURE__ */ React.createElement(ValidationMessage, {
1064
- type: "warning",
1065
- message: /* @__PURE__ */ React.createElement(React.Fragment, null, switchedManualWarning, (missingFields || []).map((f) => /* @__PURE__ */ React.createElement("div", {
1066
- key: f
1067
- }, /* @__PURE__ */ React.createElement(HelpField, {
1068
- expand: true,
1069
- id: `pipeline.config.docker.trigger.missing.${f}`
1070
- }))))
1071
- }))) : null;
1072
- if (defineManually) {
1073
- return /* @__PURE__ */ React.createElement("div", {
1074
- className: "sp-formGroup"
1075
- }, manualInputToggle, /* @__PURE__ */ React.createElement("div", {
1076
- className: "sp-formItem"
1077
- }, /* @__PURE__ */ React.createElement("div", {
1078
- className: "sp-formItem__left"
1079
- }, /* @__PURE__ */ React.createElement("div", {
1080
- className: "sp-formLabel"
1081
- }, "Image ID"), /* @__PURE__ */ React.createElement("div", {
1082
- className: "sp-formActions sp-formActions--mobile"
1083
- }, /* @__PURE__ */ React.createElement("span", {
1084
- className: "action"
1085
- }))), /* @__PURE__ */ React.createElement("div", {
1086
- className: "sp-formItem__right"
1087
- }, /* @__PURE__ */ React.createElement("div", {
1088
- className: "sp-form"
1089
- }, /* @__PURE__ */ React.createElement("span", {
1090
- className: "field"
1091
- }, /* @__PURE__ */ React.createElement("input", {
1092
- className: "form-control input-sm",
1093
- value: imageId || "",
1094
- onChange: (e) => this.valueChanged("imageId", e.target.value)
1095
- }))))), warning);
1096
- }
1097
- const Registry = showRegistry ? /* @__PURE__ */ React.createElement("div", {
1098
- className: "sp-formItem"
1099
- }, /* @__PURE__ */ React.createElement("div", {
1100
- className: "sp-formItem__left"
1101
- }, /* @__PURE__ */ React.createElement("div", {
1102
- className: "sp-formLabel"
1103
- }, "Registry Name")), /* @__PURE__ */ React.createElement("div", {
1104
- className: "sp-formItem__right"
1105
- }, /* @__PURE__ */ React.createElement("div", {
1106
- className: "sp-form"
1107
- }, /* @__PURE__ */ React.createElement("span", {
1108
- className: "field"
1109
- }, /* @__PURE__ */ React.createElement(Select, {
1110
- value: account,
1111
- disabled: imagesLoading,
1112
- onChange: (o) => this.valueChanged("account", o ? o.value : ""),
1113
- options: accountOptions,
1114
- isLoading: imagesLoading
1115
- })), /* @__PURE__ */ React.createElement("span", {
1116
- className: "sp-formActions sp-formActions--web"
1117
- }, /* @__PURE__ */ React.createElement("span", {
1118
- className: "action"
1119
- }, /* @__PURE__ */ React.createElement(Tooltip, {
1120
- value: imagesLoading ? "Images refreshing" : "Refresh images list"
1121
- }, /* @__PURE__ */ React.createElement("i", {
1122
- className: `fa icon-button-refresh-arrows ${imagesLoading ? "fa-spin" : ""}`,
1123
- onClick: this.handleRefreshImages
1124
- }))))))) : null;
1125
- const Organization = /* @__PURE__ */ React.createElement("div", {
1126
- className: "sp-formItem"
1127
- }, /* @__PURE__ */ React.createElement("div", {
1128
- className: "sp-formItem__left"
1129
- }, /* @__PURE__ */ React.createElement("div", {
1130
- className: "sp-formLabel"
1131
- }, "Organization")), /* @__PURE__ */ React.createElement("div", {
1132
- className: "sp-formItem__right"
1133
- }, /* @__PURE__ */ React.createElement("div", {
1134
- className: "sp-form"
1135
- }, /* @__PURE__ */ React.createElement("span", {
1136
- className: "field"
1137
- }, organization.includes("${") ? /* @__PURE__ */ React.createElement("input", {
1138
- disabled: imagesLoading,
1139
- className: "form-control input-sm",
1140
- value: organization || "",
1141
- onChange: (e) => this.valueChanged("organization", e.target.value)
1142
- }) : /* @__PURE__ */ React.createElement(Select, {
1143
- value: organization || "",
1144
- disabled: imagesLoading,
1145
- onChange: (o) => this.valueChanged("organization", o && o.value || ""),
1146
- placeholder: "No organization",
1147
- options: organizationOptions,
1148
- isLoading: imagesLoading
1149
- })))));
1150
- const Image = /* @__PURE__ */ React.createElement("div", {
1151
- className: "sp-formItem"
1152
- }, /* @__PURE__ */ React.createElement("div", {
1153
- className: "sp-formItem__left"
1154
- }, /* @__PURE__ */ React.createElement("div", {
1155
- className: "sp-formLabel"
1156
- }, "Image")), /* @__PURE__ */ React.createElement("div", {
1157
- className: "sp-formItem__right"
1158
- }, /* @__PURE__ */ React.createElement("div", {
1159
- className: "sp-form"
1160
- }, /* @__PURE__ */ React.createElement("span", {
1161
- className: "field"
1162
- }, repository.includes("${") ? /* @__PURE__ */ React.createElement("input", {
1163
- className: "form-control input-sm",
1164
- disabled: imagesLoading,
1165
- value: repository || "",
1166
- onChange: (e) => this.valueChanged("repository", e.target.value)
1167
- }) : /* @__PURE__ */ React.createElement(Select, {
1168
- value: repository || "",
1169
- disabled: imagesLoading,
1170
- onChange: (o) => this.valueChanged("repository", o && o.value || ""),
1171
- options: repositoryOptions,
1172
- required: true,
1173
- isLoading: imagesLoading
1174
- })))));
1175
- const Tag = lookupType === "tag" ? specifyTagByRegex ? /* @__PURE__ */ React.createElement("div", {
1176
- className: "sp-formItem"
1177
- }, /* @__PURE__ */ React.createElement("div", {
1178
- className: "sp-formItem__left"
1179
- }, /* @__PURE__ */ React.createElement("div", {
1180
- className: "sp-formLabel"
1181
- }, "Tag")), /* @__PURE__ */ React.createElement("div", {
1182
- className: "sp-formItem__right"
1183
- }, /* @__PURE__ */ React.createElement("div", {
1184
- className: "sp-form"
1185
- }, /* @__PURE__ */ React.createElement("span", {
1186
- className: "field"
1187
- }, /* @__PURE__ */ React.createElement("input", {
1188
- type: "text",
1189
- className: "form-control input-sm",
1190
- value: tag || "",
1191
- disabled: imagesLoading || !repository,
1192
- onChange: (e) => this.valueChanged("tag", e.target.value)
1193
- }))), /* @__PURE__ */ React.createElement(HelpField, {
1194
- id: "pipeline.config.docker.trigger.tag",
1195
- expand: true
1196
- }))) : /* @__PURE__ */ React.createElement("div", {
1197
- className: "sp-formItem"
1198
- }, /* @__PURE__ */ React.createElement("div", {
1199
- className: "sp-formItem__left"
1200
- }, /* @__PURE__ */ React.createElement("div", {
1201
- className: "sp-formLabel"
1202
- }, "Tag")), /* @__PURE__ */ React.createElement("div", {
1203
- className: "sp-formItem__right"
1204
- }, /* @__PURE__ */ React.createElement("div", {
1205
- className: "sp-form"
1206
- }, /* @__PURE__ */ React.createElement("span", {
1207
- className: "field"
1208
- }, tag && tag.includes("${") ? /* @__PURE__ */ React.createElement("input", {
1209
- className: "form-control input-sm",
1210
- disabled: imagesLoading,
1211
- value: tag || "",
1212
- onChange: (e) => this.valueChanged("tag", e.target.value),
1213
- required: true
1214
- }) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Select, {
1215
- value: tag || "",
1216
- disabled: imagesLoading || !repository,
1217
- isLoading: imagesLoading,
1218
- onChange: (o) => this.valueChanged("tag", o ? o.value : void 0),
1219
- options: tagOptions,
1220
- placeholder: "No tag",
1221
- required: true
1222
- }), /* @__PURE__ */ React.createElement(HelpField, {
1223
- id: "pipeline.config.docker.trigger.tag.additionalInfo",
1224
- expand: true
1225
- })))))) : null;
1226
- const Digest = lookupType === "digest" ? /* @__PURE__ */ React.createElement("div", {
1227
- className: "sp-formItem"
1228
- }, /* @__PURE__ */ React.createElement("div", {
1229
- className: "sp-formItem__left"
1230
- }, /* @__PURE__ */ React.createElement("div", {
1231
- className: "sp-formLabel"
1232
- }, "Digest ", /* @__PURE__ */ React.createElement(HelpField, {
1233
- id: "pipeline.config.docker.trigger.digest"
1234
- }))), /* @__PURE__ */ React.createElement("div", {
1235
- className: "sp-formItem__right"
1236
- }, /* @__PURE__ */ React.createElement("div", {
1237
- className: "sp-form"
1238
- }, /* @__PURE__ */ React.createElement("span", {
1239
- className: "field"
1240
- }, /* @__PURE__ */ React.createElement("input", {
1241
- className: "form-control input-sm",
1242
- placeholder: "sha256:abc123",
1243
- value: digest || parsedImageId.digest || "",
1244
- onChange: (e) => this.valueChanged("digest", e.target.value),
1245
- required: true
1246
- }))))) : null;
1247
- const LookupTypeSelector = showDigest ? /* @__PURE__ */ React.createElement("div", {
1248
- className: "sp-formItem"
1249
- }, /* @__PURE__ */ React.createElement("div", {
1250
- className: "sp-formItem__left"
1251
- }, /* @__PURE__ */ React.createElement("div", {
1252
- className: "sp-formLabel"
1253
- }, "Type")), /* @__PURE__ */ React.createElement("div", {
1254
- className: "sp-formItem__right"
1255
- }, /* @__PURE__ */ React.createElement("div", {
1256
- className: "sp-form"
1257
- }, /* @__PURE__ */ React.createElement("span", {
1258
- className: "field"
1259
- }, /* @__PURE__ */ React.createElement(Select, {
1260
- clearable: false,
1261
- value: lookupType,
1262
- options: [
1263
- { value: "digest", label: "Digest" },
1264
- { value: "tag", label: "Tag" }
1265
- ],
1266
- onChange: this.lookupTypeChanged
1267
- }))))) : null;
1268
- return /* @__PURE__ */ React.createElement("div", {
1269
- className: "sp-formGroup"
1270
- }, manualInputToggle, Registry, Organization, Image, LookupTypeSelector, Digest, Tag);
1271
- }
1272
- }
1273
- DockerChartAndTagSelector.defaultProps = {
1274
- organization: "",
1275
- registry: "",
1276
- repository: "",
1277
- showDigest: true,
1278
- allowManualDefinition: true
1279
- };
1280
-
1281
- function DockerHelmOciTriggerConfig(props) {
1282
- const { formik } = props;
1283
- const trigger = formik.values;
1284
- const dockerChanged = (changes) => {
1285
- const { imageId, ...rest } = changes;
1286
- props.triggerUpdated(rest);
1287
- };
1288
- return /* @__PURE__ */ React.createElement("div", {
1289
- className: "form-horizontal"
1290
- }, /* @__PURE__ */ React.createElement(DockerChartAndTagSelector, {
1291
- allowManualDefinition: false,
1292
- specifyTagByRegex: true,
1293
- account: trigger.account,
1294
- organization: trigger.organization,
1295
- registry: trigger.registry,
1296
- repository: trigger.repository,
1297
- tag: trigger.tag,
1298
- showRegistry: true,
1299
- onChange: dockerChanged,
1300
- showDigest: false
1301
- }));
1302
- }
1303
-
1304
- function DockerTriggerConfig(props) {
1305
- const { formik } = props;
1306
- const trigger = formik.values;
1307
- const dockerChanged = (changes) => {
1308
- const { imageId, ...rest } = changes;
1309
- props.triggerUpdated(rest);
1310
- };
1311
- return /* @__PURE__ */ React.createElement("div", {
1312
- className: "form-horizontal"
1313
- }, /* @__PURE__ */ React.createElement(DockerImageAndTagSelector, {
1314
- allowManualDefinition: false,
1315
- specifyTagByRegex: true,
1316
- account: trigger.account,
1317
- organization: trigger.organization,
1318
- registry: trigger.registry,
1319
- repository: trigger.repository,
1320
- tag: trigger.tag,
1321
- showRegistry: true,
1322
- onChange: dockerChanged,
1323
- showDigest: false
1324
- }));
1325
- }
1326
-
1327
- const lookupTypeOptions = [
1328
- { value: "digest", label: "Digest" },
1329
- { value: "tag", label: "Tag" }
1330
- ];
1331
- class DockerTriggerTemplate extends React.Component {
1332
- constructor(props) {
1333
- super(props);
1334
- this.queryStream = new Subject();
1335
- this.handleQuery = () => {
1336
- const trigger = this.props.command.trigger;
1337
- if (trigger.type === "helm/oci") {
1338
- return from(DockerChartImageReader.findTags({
1339
- provider: "dockerRegistry",
1340
- account: trigger.account,
1341
- repository: trigger.repository
1342
- }));
1343
- } else {
1344
- return from(DockerImageReader.findTags({
1345
- provider: "dockerRegistry",
1346
- account: trigger.account,
1347
- repository: trigger.repository
1348
- }));
1349
- }
1350
- };
1351
- this.lookupTypeChanged = (o) => {
1352
- const newType = o.value;
1353
- this.updateArtifact(this.props.command, newType === "tag" ? this.state.selectedTag : this.state.digest);
1354
- this.setState({ lookupType: newType });
1355
- };
1356
- this.updateSelectedTag = (tag) => {
1357
- this.updateArtifact(this.props.command, tag);
1358
- this.setState({ selectedTag: tag });
1359
- this.props.command.triggerInvalid = false;
1360
- };
1361
- this.updateDigest = (digest) => {
1362
- this.updateArtifact(this.props.command, digest);
1363
- this.setState({ digest });
1364
- };
1365
- this.tagLoadSuccess = (tags) => {
1366
- const { command } = this.props;
1367
- const trigger = command.trigger;
1368
- const newState = {};
1369
- newState.tags = tags || [];
1370
- const defaultSelection = newState.tags.find((t) => t === trigger.tag);
1371
- if (defaultSelection) {
1372
- newState.selectedTag = defaultSelection;
1373
- this.updateSelectedTag(defaultSelection);
1374
- }
1375
- newState.tagsLoading = false;
1376
- this.setState(newState);
1377
- };
1378
- this.tagLoadFailure = () => {
1379
- this.setState({
1380
- tagsLoading: false,
1381
- loadError: true
1382
- });
1383
- };
1384
- this.initialize = () => {
1385
- const { command } = this.props;
1386
- this.props.updateCommand("triggerInvalid", true);
1387
- this.props.updateCommand("extraFields", {
1388
- tag: get(command, "extraFields.tag", ""),
1389
- artifacts: get(command, "extraFields.artifacts", "")
1390
- });
1391
- if (this.subscription) {
1392
- this.subscription.unsubscribe();
1393
- }
1394
- if (command.trigger.type !== "docker" && command.trigger.type !== "helm/oci") {
1395
- return;
1396
- }
1397
- this.subscription = this.queryStream.pipe(debounceTime(250), switchMap(this.handleQuery)).subscribe(this.tagLoadSuccess, this.tagLoadFailure);
1398
- this.searchTags();
1399
- };
1400
- this.searchTags = (query = "") => {
1401
- this.setState({ tags: [`<span>Finding tags${query && ` matching ${query}`}...</span>`] });
1402
- this.queryStream.next();
1403
- };
1404
- this.state = {
1405
- digest: "",
1406
- tags: [],
1407
- tagsLoading: true,
1408
- loadError: false,
1409
- lookupType: "tag",
1410
- selectedTag: ""
1411
- };
1412
- }
1413
- static formatLabel(trigger) {
1414
- return $q.when(`(Docker Registry) ${trigger.account ? trigger.account + ":" : ""} ${trigger.repository || ""}`);
1415
- }
1416
- updateArtifact(command, tagOrDigest) {
1417
- this.props.updateCommand("extraFields.tag", tagOrDigest);
1418
- const trigger = command.trigger;
1419
- if (trigger && trigger.repository) {
1420
- let imageName = "";
1421
- if (trigger.registry) {
1422
- imageName += trigger.registry + "/";
1423
- }
1424
- imageName += trigger.repository;
1425
- let imageReference = "";
1426
- if (this.state.lookupType === "digest") {
1427
- imageReference = `${imageName}@${tagOrDigest}`;
1428
- } else {
1429
- imageReference = `${imageName}:${tagOrDigest}`;
1430
- }
1431
- const artifactType = trigger.type === "docker" ? "docker/image" : "helm/image";
1432
- this.props.updateCommand("extraFields.artifacts", [
1433
- {
1434
- type: artifactType,
1435
- name: imageName,
1436
- version: tagOrDigest,
1437
- reference: imageReference
1438
- }
1439
- ]);
1440
- }
1441
- }
1442
- componentDidMount() {
1443
- this.initialize();
1444
- }
1445
- componentWillUnmount() {
1446
- if (this.subscription) {
1447
- this.subscription.unsubscribe();
1448
- }
1449
- }
1450
- render() {
1451
- const { digest, tags, tagsLoading, loadError, selectedTag, lookupType } = this.state;
1452
- const options = tags.map((tag) => {
1453
- return { value: tag };
1454
- });
1455
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", {
1456
- className: "form-group"
1457
- }, /* @__PURE__ */ React.createElement("div", {
1458
- className: "sm-label-right col-md-4"
1459
- }, "Type"), /* @__PURE__ */ React.createElement("div", {
1460
- className: "col-md-3"
1461
- }, /* @__PURE__ */ React.createElement(TetheredSelect, {
1462
- clearable: false,
1463
- value: lookupType,
1464
- options: lookupTypeOptions,
1465
- onChange: this.lookupTypeChanged
1466
- }))), lookupType === "tag" && /* @__PURE__ */ React.createElement("div", {
1467
- className: "form-group"
1468
- }, /* @__PURE__ */ React.createElement("label", {
1469
- className: "col-md-4 sm-label-right"
1470
- }, "Tag"), tagsLoading && /* @__PURE__ */ React.createElement("div", {
1471
- className: "col-md-6"
1472
- }, /* @__PURE__ */ React.createElement("div", {
1473
- className: "form-control-static text-center"
1474
- }, /* @__PURE__ */ React.createElement(Spinner, {
1475
- size: "small"
1476
- }))), loadError && /* @__PURE__ */ React.createElement("div", {
1477
- className: "col-md-6"
1478
- }, "Error loading tags!"), !tagsLoading && /* @__PURE__ */ React.createElement("div", {
1479
- className: "col-md-6"
1480
- }, tags.length === 0 && /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", {
1481
- className: "form-control-static"
1482
- }, "No tags found")), tags.length > 0 && /* @__PURE__ */ React.createElement(TetheredSelect, {
1483
- options,
1484
- optionRenderer: (o) => /* @__PURE__ */ React.createElement("span", null, o.value),
1485
- clearable: false,
1486
- value: selectedTag,
1487
- valueRenderer: (o) => /* @__PURE__ */ React.createElement("span", null, /* @__PURE__ */ React.createElement("strong", null, o.value)),
1488
- onChange: (o) => this.updateSelectedTag(o.value),
1489
- placeholder: "Search tags..."
1490
- }))), lookupType === "digest" && /* @__PURE__ */ React.createElement("div", {
1491
- className: "form-group"
1492
- }, /* @__PURE__ */ React.createElement("label", {
1493
- className: "col-md-4 sm-label-right"
1494
- }, "Digest ", /* @__PURE__ */ React.createElement(HelpField, {
1495
- id: "pipeline.config.docker.trigger.digest"
1496
- })), /* @__PURE__ */ React.createElement("div", {
1497
- className: "col-md-6"
1498
- }, /* @__PURE__ */ React.createElement("input", {
1499
- value: digest,
1500
- onChange: (e) => this.updateDigest(e.target.value),
1501
- className: "form-control input-sm",
1502
- required: true
1503
- }))));
1504
- }
1505
- }
1506
-
1507
- const DockerTriggerExecutionStatus = (props) => {
1508
- const trigger = props.trigger;
1509
- return /* @__PURE__ */ React.createElement("li", null, trigger.repository, ":", trigger.tag);
1510
- };
1511
- Registry.pipeline.registerTrigger({
1512
- label: "Docker Registry",
1513
- description: "Executes the pipeline on an image update",
1514
- key: "docker",
1515
- component: DockerTriggerConfig,
1516
- manualExecutionComponent: DockerTriggerTemplate,
1517
- executionStatusComponent: DockerTriggerExecutionStatus,
1518
- executionTriggerLabel: () => "Docker Registry",
1519
- validators: [
1520
- {
1521
- type: "requiredField",
1522
- fieldName: "account",
1523
- message: "<strong>Registry</strong> is a required field for Docker Registry triggers."
1524
- },
1525
- {
1526
- type: "requiredField",
1527
- fieldName: "repository",
1528
- message: "<strong>Image</strong> is a required field for Docker Registry triggers."
1529
- },
1530
- {
1531
- type: "serviceAccountAccess",
1532
- preventSave: true,
1533
- message: `You do not have access to the service account configured in this pipeline's Docker Registry trigger.
1534
- You will not be able to save your edits to this pipeline.`
1535
- }
1536
- ]
1537
- });
1538
- Registry.pipeline.registerTrigger({
1539
- label: "Helm Docker Registry",
1540
- description: "Executes the pipeline on an helm/image update",
1541
- key: "helm/oci",
1542
- component: DockerHelmOciTriggerConfig,
1543
- manualExecutionComponent: DockerTriggerTemplate,
1544
- executionStatusComponent: DockerTriggerExecutionStatus,
1545
- executionTriggerLabel: () => "Helm Docker Registry",
1546
- validators: [
1547
- {
1548
- type: "requiredField",
1549
- fieldName: "account",
1550
- message: "<strong>Registry</strong> is a required field for Docker Registry triggers."
1551
- },
1552
- {
1553
- type: "requiredField",
1554
- fieldName: "repository",
1555
- message: "<strong>Image</strong> is a required field for Docker Registry triggers."
1556
- },
1557
- {
1558
- type: "serviceAccountAccess",
1559
- preventSave: true,
1560
- message: `You do not have access to the service account configured in this pipeline's Docker Registry trigger.
1561
- You will not be able to save your edits to this pipeline.`
1562
- }
1563
- ]
1564
- });
1565
-
1566
- const DOCKER_MODULE = "spinnaker.docker";
1567
- module(DOCKER_MODULE, [DOCKER_PIPELINE_STAGES_BAKE_DOCKERBAKESTAGE]);
1568
-
1569
- export { DOCKER_MODULE, DockerChartImageReader, DockerImageAndTagSelector, DockerImageReader, DockerImageUtils };
1
+ import{REST as e,RetryService as t,AccountService as a,ValidationMessage as s,HelpField as i,Tooltip as n,SETTINGS as o,Registry as r,BakeExecutionLabel as l,AuthenticationService as c,BakeryReader as g,TetheredSelect as m,Spinner as p}from"@spinnaker/core";import d,{groupBy as u,reduce as h,uniq as f,trim as v,get as y}from"lodash";import E from"react";import b from"react-select";import{module as N}from"angular";import I from"@uirouter/angularjs";import{$q as k}from"ngimport";import{Subject as C,from as z}from"rxjs";import{debounceTime as _,switchMap as w}from"rxjs/operators";class L{static getImage(t,a,s){return e("/images").path(s,a,t).query({provider:"docker"}).get().then((e=>e&&e.length?e[0]:null)).catch((()=>null))}static findImages(a){return t.buildRetrySequence((()=>e("/images/find").query(a).get()),(e=>e.length>0),10,1e3).then((e=>e)).catch((()=>[]))}static findTags(a){return t.buildRetrySequence((()=>e("/images/tags").query(a).get()),(e=>e.length>0),10,1e3).then((e=>e)).catch((()=>[]))}}class M{static getImage(t,a,s){return e("/charts").path(s,a,t).query({provider:"docker"}).get().then((e=>e&&e.length?e[0]:null)).catch((()=>null))}static findImages(a){return t.buildRetrySequence((()=>e("/charts/find").query(a).get()),(e=>e.length>0),10,1e3).then((e=>e)).catch((()=>[]))}static findTags(a){return t.buildRetrySequence((()=>e("/charts/tags").query(a).get()),(e=>e.length>0),10,1e3).then((e=>e)).catch((()=>[]))}}class R{static splitImageId(e=""){let t;t=e.includes("@")?e.split("@"):e.split(":");const a=t[0],s=a.split("/").slice(0,-1).join("/"),i=t.length>1?t.slice(1).join(":"):"";let n,o;return i&&(i.startsWith("sha256:")?o=i:n=i),{organization:s,repository:a,digest:o,tag:n}}static generateImageId(e){if(!e.repository||!e.digest&&!e.tag)return;let t;return t=e.digest?`${e.repository}@${e.digest}`:`${e.repository}:${e.tag}`,t}}const x=["organization","repository","tag","digest"],T=[{label:"Manually",value:!0},{label:"Select from list",value:!1}];class S extends E.Component{constructor(e){super(e),this.unmounted=!1,this.cachedValues={},this.handleRefreshImages=()=>{this.refreshImages(this.props)},this.lookupTypeChanged=e=>{const t=e.value,a=this.state.lookupType,s=this.props[a],i=this.cachedValues[t];this.valueChanged(a,void 0),this.cachedValues[t]&&this.valueChanged(t,i),this.setState({lookupType:t}),this.cachedValues[a]=s},this.showManualInput=e=>{if(!e){const e=R.splitImageId(this.props.imageId||"");this.props.onChange(e),this.state.switchedManualWarning&&this.setState({switchedManualWarning:void 0,missingFields:void 0})}this.setState({defineManually:e})};const t=e.account?[{label:e.account,value:e.account}]:[],a=e.organization&&e.organization.length?[{label:e.organization,value:e.organization}]:[],s=e.repository&&e.repository.length?[{label:e.repository,value:e.repository}]:[],i=e.tag&&e.tag.length?[{label:e.tag,value:e.tag}]:[],n=R.splitImageId(e.imageId),o=e.allowManualDefinition&&Boolean(e.imageId&&e.imageId.includes("${"));this.state={accountOptions:t,switchedManualWarning:void 0,imagesLoaded:!1,imagesLoading:!1,organizationOptions:a,repositoryOptions:s,defineManually:o,tagOptions:i,lookupType:e.digest||n.digest?"digest":"tag"}}getAccountMap(e){const t=u(e.filter((e=>e.account)),"account");return h(t,((e,t,a)=>(e[a]=f(t.map((e=>`${e.repository.split("/").slice(0,-1).join("/")}`))),e)),{})}getRegistryMap(e){return e.reduce(((e,t)=>(e[t.account]=t.registry,e)),{})}getOrganizationMap(e){const t=u(e.filter((e=>e.repository)),(e=>`${e.account}/${e.repository.split("/").slice(0,-1).join("/")}`));return h(t,((e,t,a)=>(e[a]=f(t.map((e=>e.repository))),e)),{})}getRepositoryMap(e){const t=u(e.filter((e=>e.account)),"repository");return h(t,((e,t,a)=>(e[a]=f(t.map((e=>e.tag))),e)),{})}getOrganizationsList(e){return e&&e[this.props.showRegistry?this.props.account:this.props.registry]||[]}getRepositoryList(e,t,a){if(e){return e[`${this.props.showRegistry?this.props.account:a}/${t||""}`]||[]}return[]}getTags(e,t,a){let s=[];return this.props.specifyTagByRegex?e&&""===v(e)&&(e=void 0):t&&(s=t[a]||[],s.includes(e)||!e||e.includes("${")||(e=void 0)),{tag:e,tags:s}}componentWillReceiveProps(e){!this.images||["account","showRegistry"].some((t=>this.props[t]!==e[t]))?this.refreshImages(e):["organization","registry","repository"].some((t=>this.props[t]!==e[t]))&&this.updateThings(e),e.imageId&&e.imageId.includes("${")&&this.setState({defineManually:!0})}componentWillUnmount(){this.unmounted=!0}synchronizeChanges(e,t){const{organization:a,repository:s,tag:i,digest:n}=e;if(this.props.onChange){const e=R.generateImageId({organization:a,repository:s,tag:i,digest:n}),o={};i!==this.props.tag&&(o.tag=i),e!==this.props.imageId&&(o.imageId=e),a!==this.props.organization&&(o.organization=a),t!==this.props.registry&&(o.registry=t),s!==this.props.repository&&(o.repository=s),n!==this.props.digest&&(o.digest=n),Object.keys(o).length>0&&this.props.onChange(o)}}updateThings(e,t=!1){if(!this.repositoryMap||this.unmounted)return;const{imageId:a,specifyTagByRegex:s}=e;let{organization:i,registry:n,repository:o}=e;e.showRegistry&&(n=this.registryMap[e.account]);const r=!i||this.organizations.includes(i)||i.includes("${");r||(i="");const l=this.getRepositoryList(this.organizationMap,i,n),c=!o||o.includes("${")||l.includes(o);c||(o="");const{tag:g,tags:m}=this.getTags(e.tag,this.repositoryMap,o),p=g===e.tag||s,d={accountOptions:this.newAccounts.sort().map((e=>({label:e,value:e}))),organizationOptions:this.organizations.filter((e=>e)).sort().map((e=>({label:e,value:e}))),imagesLoaded:!0,repositoryOptions:l.sort().map((e=>({label:e,value:e}))),tagOptions:m.sort().map((e=>({label:e,value:e})))};if(!a||this.state.imagesLoaded&&!t||r&&c&&p)a&&a.includes("${")||this.synchronizeChanges(this.state.defineManually?R.splitImageId(a):{organization:i,repository:o,tag:g,digest:this.props.digest},n);else{d.defineManually=!0;const e=[];r||e.push("organization"),c||e.push("image"),p||e.push("tag"),d.missingFields=e,d.switchedManualWarning=`Could not find ${e.join(" or ")}, switched to manual entry`}this.setState(d)}initializeImages(e){if(this.state.imagesLoading)return;const{showRegistry:t,account:a,registry:s}=e,i={provider:"dockerRegistry",account:t?a:s};this.setState({imagesLoading:!0}),L.findImages(i).then((t=>{this.images=t,this.registryMap=this.getRegistryMap(this.images),this.accountMap=this.getAccountMap(this.images),this.newAccounts=this.accounts||Object.keys(this.accountMap),this.organizationMap=this.getOrganizationMap(this.images),this.repositoryMap=this.getRepositoryMap(this.images),this.organizations=this.getOrganizationsList(this.accountMap),this.updateThings(e,!0)})).finally((()=>{this.unmounted||this.setState({imagesLoading:!1})}))}refreshImages(e){this.initializeImages(e)}initializeAccounts(e){let{account:t}=e;a.listAccounts("dockerRegistry").then((a=>{const s=a.map((e=>e.name));this.props.showRegistry&&!t&&(t=s[0]),this.accounts=s,this.refreshImages({...e,account:t})}))}isNew(){const{account:e,organization:t,registry:a,repository:s,tag:i}=this.props;return!(e||t||a||s||i)}componentDidMount(){this.props.deferInitialization||!this.props.registry&&!this.isNew()||this.initializeAccounts(this.props)}valueChanged(e,t){const a={[e]:t};if(x.some((t=>t===e))){const{organization:e,repository:t,tag:s,digest:i}=this.props,n={organization:e,repository:t,tag:s,digest:i,...a},o=R.generateImageId(n);a.imageId=o}this.props.onChange&&this.props.onChange(a)}render(){const{account:e,allowManualDefinition:t,digest:a,imageId:o,organization:r,repository:l,showDigest:c,showRegistry:g,specifyTagByRegex:m,tag:p}=this.props,{accountOptions:d,switchedManualWarning:u,missingFields:h,imagesLoading:f,lookupType:v,organizationOptions:y,repositoryOptions:N,defineManually:I,tagOptions:k}=this.state,C=R.splitImageId(o),z=E.createElement("div",{className:"sp-formItem groupHeader"},E.createElement("div",{className:"sp-formItem__left"},E.createElement("div",{className:"sp-formLabel"},"Define Image ID"),E.createElement("div",{className:"sp-formActions sp-formActions--mobile"},E.createElement("span",{className:"action"}))),E.createElement("div",{className:"sp-formItem__right"},E.createElement("div",{className:"sp-form"},E.createElement("span",{className:"field"},E.createElement(b,{value:I,disabled:f||!t,onChange:e=>this.showManualInput(e.value),options:T,clearable:!1}))))),_=u?E.createElement("div",{className:"sp-formItem"},E.createElement("div",{className:"sp-formItem__left"}),E.createElement("div",{className:"sp-formItem__right"},E.createElement(s,{type:"warning",message:E.createElement(E.Fragment,null,u,(h||[]).map((e=>E.createElement("div",{key:e},E.createElement(i,{expand:!0,id:`pipeline.config.docker.trigger.missing.${e}`})))))}))):null;if(I)return E.createElement("div",{className:"sp-formGroup"},z,E.createElement("div",{className:"sp-formItem"},E.createElement("div",{className:"sp-formItem__left"},E.createElement("div",{className:"sp-formLabel"},"Image ID"),E.createElement("div",{className:"sp-formActions sp-formActions--mobile"},E.createElement("span",{className:"action"}))),E.createElement("div",{className:"sp-formItem__right"},E.createElement("div",{className:"sp-form"},E.createElement("span",{className:"field"},E.createElement("input",{className:"form-control input-sm",value:o||"",onChange:e=>this.valueChanged("imageId",e.target.value)}))))),_);const w=g?E.createElement("div",{className:"sp-formItem"},E.createElement("div",{className:"sp-formItem__left"},E.createElement("div",{className:"sp-formLabel"},"Registry Name")),E.createElement("div",{className:"sp-formItem__right"},E.createElement("div",{className:"sp-form"},E.createElement("span",{className:"field"},E.createElement(b,{value:e,disabled:f,onChange:e=>this.valueChanged("account",e?e.value:""),options:d,isLoading:f})),E.createElement("span",{className:"sp-formActions sp-formActions--web"},E.createElement("span",{className:"action"},E.createElement(n,{value:f?"Images refreshing":"Refresh images list"},E.createElement("i",{className:"fa icon-button-refresh-arrows "+(f?"fa-spin":""),onClick:this.handleRefreshImages}))))))):null,L=E.createElement("div",{className:"sp-formItem"},E.createElement("div",{className:"sp-formItem__left"},E.createElement("div",{className:"sp-formLabel"},"Organization")),E.createElement("div",{className:"sp-formItem__right"},E.createElement("div",{className:"sp-form"},E.createElement("span",{className:"field"},r.includes("${")?E.createElement("input",{disabled:f,className:"form-control input-sm",value:r||"",onChange:e=>this.valueChanged("organization",e.target.value)}):E.createElement(b,{value:r||"",disabled:f,onChange:e=>this.valueChanged("organization",e&&e.value||""),placeholder:"No organization",options:y,isLoading:f}))))),M=E.createElement("div",{className:"sp-formItem"},E.createElement("div",{className:"sp-formItem__left"},E.createElement("div",{className:"sp-formLabel"},"Image")),E.createElement("div",{className:"sp-formItem__right"},E.createElement("div",{className:"sp-form"},E.createElement("span",{className:"field"},l.includes("${")?E.createElement("input",{className:"form-control input-sm",disabled:f,value:l||"",onChange:e=>this.valueChanged("repository",e.target.value)}):E.createElement(b,{value:l||"",disabled:f,onChange:e=>this.valueChanged("repository",e&&e.value||""),options:N,required:!0,isLoading:f}))))),x="tag"===v?m?E.createElement("div",{className:"sp-formItem"},E.createElement("div",{className:"sp-formItem__left"},E.createElement("div",{className:"sp-formLabel"},"Tag")),E.createElement("div",{className:"sp-formItem__right"},E.createElement("div",{className:"sp-form"},E.createElement("span",{className:"field"},E.createElement("input",{type:"text",className:"form-control input-sm",value:p||"",disabled:f||!l,onChange:e=>this.valueChanged("tag",e.target.value)}))),E.createElement(i,{id:"pipeline.config.docker.trigger.tag",expand:!0}))):E.createElement("div",{className:"sp-formItem"},E.createElement("div",{className:"sp-formItem__left"},E.createElement("div",{className:"sp-formLabel"},"Tag")),E.createElement("div",{className:"sp-formItem__right"},E.createElement("div",{className:"sp-form"},E.createElement("span",{className:"field"},p&&p.includes("${")?E.createElement("input",{className:"form-control input-sm",disabled:f,value:p||"",onChange:e=>this.valueChanged("tag",e.target.value),required:!0}):E.createElement(E.Fragment,null,E.createElement(b,{value:p||"",disabled:f||!l,isLoading:f,onChange:e=>this.valueChanged("tag",e?e.value:void 0),options:k,placeholder:"No tag",required:!0}),E.createElement(i,{id:"pipeline.config.docker.trigger.tag.additionalInfo",expand:!0})))))):null,S="digest"===v?E.createElement("div",{className:"sp-formItem"},E.createElement("div",{className:"sp-formItem__left"},E.createElement("div",{className:"sp-formLabel"},"Digest ",E.createElement(i,{id:"pipeline.config.docker.trigger.digest"}))),E.createElement("div",{className:"sp-formItem__right"},E.createElement("div",{className:"sp-form"},E.createElement("span",{className:"field"},E.createElement("input",{className:"form-control input-sm",placeholder:"sha256:abc123",value:a||C.digest||"",onChange:e=>this.valueChanged("digest",e.target.value),required:!0}))))):null,O=c?E.createElement("div",{className:"sp-formItem"},E.createElement("div",{className:"sp-formItem__left"},E.createElement("div",{className:"sp-formLabel"},"Type")),E.createElement("div",{className:"sp-formItem__right"},E.createElement("div",{className:"sp-form"},E.createElement("span",{className:"field"},E.createElement(b,{clearable:!1,value:v,options:[{value:"digest",label:"Digest"},{value:"tag",label:"Tag"}],onChange:this.lookupTypeChanged}))))):null;return E.createElement("div",{className:"sp-formGroup"},z,w,L,M,O,S,x)}}S.defaultProps={organization:"",registry:"",repository:"",showDigest:!0,allowManualDefinition:!0};const O="spinnaker.docker.pipeline.stage.bake.executionDetails.controller";N(O,[I]).controller("dockerBakeExecutionDetailsCtrl",["$scope","$stateParams","executionDetailsSectionService","$interpolate",function(e,t,a,s){e.configSections=["bakeConfig","taskStatus"];const i=()=>{e.detailsSection=t.details,e.provider=e.stage.context.cloudProviderType||"docker",e.bakeryDetailUrl=s(e.roscoMode&&o.roscoDetailUrl?o.roscoDetailUrl:o.bakeryDetailUrl)},n=()=>a.synchronizeSection(e.configSections,i);n(),e.$on("$stateChangeSuccess",n)}]);const D="spinnaker.docker.pipeline.stage.bakeStage";N(D,[O]).config((function(){r.pipeline.registerStage({provides:"bake",cloudProvider:"docker",label:"Bake",description:"Bakes an image",templateUrl:"docker/src/pipeline/stages/bake/bakeStage.html",executionDetailsUrl:"docker/src/pipeline/stages/bake/bakeExecutionDetails.html",executionLabelComponent:l,extraLabelLines:e=>e.masterStage.context.allPreviouslyBaked||e.masterStage.context.somePreviouslyBaked?1:0,supportsCustomTimeout:!0,validators:[{type:"requiredField",fieldName:"package"}],restartable:!0})})).controller("dockerBakeStageCtrl",["$scope","$q",function(e,t){e.stage.region="global",e.stage.user||(e.stage.user=c.getAuthenticatedUser().name),e.viewState={loading:!0},e.$watch("stage",(function(){d.forOwn(e.stage,(function(t,a){""===t&&delete e.stage[a]}))}),!0),e.viewState.providerSelected=!0,t.all([g.getBaseOsOptions("docker"),g.getBaseLabelOptions()]).then((function([t,a]){e.baseOsOptions=t.baseImages,e.baseLabelOptions=a,!e.stage.baseOs&&e.baseOsOptions&&e.baseOsOptions.length&&(e.stage.baseOs=e.baseOsOptions[0].id),!e.stage.baseLabel&&e.baseLabelOptions&&e.baseLabelOptions.length&&(e.stage.baseLabel=e.baseLabelOptions[0]),e.viewState.loading=!1}))}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("docker/src/pipeline/stages/bake/bakeStage.html",'<div ng-controller="dockerBakeStageCtrl as bakeStageCtrl">\n <stage-config-field label="Package" help-key="pipeline.config.bake.package">\n <input type="text" class="form-control input-sm" ng-model="stage.package" />\n </stage-config-field>\n <stage-config-field label="Organization" help-key="pipeline.config.docker.bake.organization">\n <input type="text" class="form-control input-sm" ng-model="stage.organization" />\n </stage-config-field>\n <stage-config-field label="Image Name" help-key="pipeline.config.docker.bake.targetImage">\n <input type="text" class="form-control input-sm" ng-model="stage.ami_name" />\n </stage-config-field>\n <stage-config-field label="Image tag" help-key="pipeline.config.docker.bake.targetImageTag">\n <input type="text" class="form-control input-sm" ng-model="stage.extendedAttributes[\'docker_target_image_tag\']" />\n </stage-config-field>\n <stage-config-field label="Base OS">\n <bake-stage-choose-os model="stage.baseOs" base-os-options="baseOsOptions"></bake-stage-choose-os>\n </stage-config-field>\n\n <stage-config-field label="Base Label">\n <label class="radio-inline" ng-repeat="baseLabel in baseLabelOptions">\n <input type="radio" ng-model="stage.baseLabel" ng-value="baseLabel" />\n {{baseLabel}}\n </label>\n </stage-config-field>\n <stage-config-field label="Rebake">\n <div class="checkbox" style="margin-bottom: 0">\n <label>\n <input type="checkbox" ng-model="stage.rebake" />\n Rebake image without regard to the status of any existing bake\n </label>\n </div>\n </stage-config-field>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("docker/src/pipeline/stages/bake/bakeExecutionDetails.html",'<div ng-controller="dockerBakeExecutionDetailsCtrl">\n <execution-details-section-nav sections="configSections"></execution-details-section-nav>\n <div class="step-section-details" ng-if="detailsSection === \'bakeConfig\'">\n <div class="row">\n <div class="col-md-6">\n <dl class="dl-narrow dl-horizontal">\n <dt if-multiple-providers>Provider</dt>\n <dd if-multiple-providers>Docker</dd>\n <dt>Organization</dt>\n <dd>{{stage.context.organization}}</dd>\n <dt>Image Name</dt>\n <dd>{{stage.context.ami_name}}</dd>\n <dt>Image Tag</dt>\n <dd>{{stage.context.extendedAttributes[\'docker_target_image_tag\']}}</dd>\n <dt>Image</dt>\n <dd>{{stage.context.ami}}</dd>\n </dl>\n </div>\n <div class="col-md-6">\n <dl class="dl-narrow dl-horizontal">\n <dt>Base OS</dt>\n <dd>{{stage.context.baseOs}}</dd>\n <dt>Region</dt>\n <dd>{{stage.context.region}}</dd>\n <dt>Package</dt>\n <dd>{{stage.context.package}}</dd>\n <dt>Label</dt>\n <dd>{{stage.context.baseLabel}}</dd>\n </dl>\n </div>\n </div>\n <stage-failure-message stage="stage" message="stage.failureMessage"></stage-failure-message>\n\n <div class="row" ng-if="stage.context.region && stage.context.status.resourceId">\n <div class="col-md-12">\n <div class="alert alert-{{stage.isFailed ? \'danger\' : \'info\'}}">\n <a target="_blank" href="{{ bakeryDetailUrl(stage) }}"> View Bakery Details </a>\n </div>\n </div>\n </div>\n </div>\n <div class="step-section-details" ng-if="detailsSection === \'taskStatus\'">\n <div class="row">\n <execution-step-details item="stage"></execution-step-details>\n </div>\n </div>\n</div>\n')}]);const $=["organization","repository","tag","digest"],A=[{label:"Manually",value:!0},{label:"Select from list",value:!1}];class q extends E.Component{constructor(e){super(e),this.unmounted=!1,this.cachedValues={},this.handleRefreshImages=()=>{this.refreshImages(this.props)},this.lookupTypeChanged=e=>{const t=e.value,a=this.state.lookupType,s=this.props[a],i=this.cachedValues[t];this.valueChanged(a,void 0),this.cachedValues[t]&&this.valueChanged(t,i),this.setState({lookupType:t}),this.cachedValues[a]=s},this.showManualInput=e=>{if(!e){const e=R.splitImageId(this.props.imageId||"");this.props.onChange(e),this.state.switchedManualWarning&&this.setState({switchedManualWarning:void 0,missingFields:void 0})}this.setState({defineManually:e})};const t=e.account?[{label:e.account,value:e.account}]:[],a=e.organization&&e.organization.length?[{label:e.organization,value:e.organization}]:[],s=e.repository&&e.repository.length?[{label:e.repository,value:e.repository}]:[],i=e.tag&&e.tag.length?[{label:e.tag,value:e.tag}]:[],n=R.splitImageId(e.imageId),o=e.allowManualDefinition&&Boolean(e.imageId&&e.imageId.includes("${"));this.state={accountOptions:t,switchedManualWarning:void 0,imagesLoaded:!1,imagesLoading:!1,organizationOptions:a,repositoryOptions:s,defineManually:o,tagOptions:i,lookupType:e.digest||n.digest?"digest":"tag"}}getAccountMap(e){const t=u(e.filter((e=>e.account)),"account");return h(t,((e,t,a)=>(e[a]=f(t.map((e=>`${e.repository.split("/").slice(0,-1).join("/")}`))),e)),{})}getRegistryMap(e){return e.reduce(((e,t)=>(e[t.account]=t.registry,e)),{})}getOrganizationMap(e){const t=u(e.filter((e=>e.repository)),(e=>`${e.account}/${e.repository.split("/").slice(0,-1).join("/")}`));return h(t,((e,t,a)=>(e[a]=f(t.map((e=>e.repository))),e)),{})}getRepositoryMap(e){const t=u(e.filter((e=>e.account)),"repository");return h(t,((e,t,a)=>(e[a]=f(t.map((e=>e.tag))),e)),{})}getOrganizationsList(e){return e&&e[this.props.showRegistry?this.props.account:this.props.registry]||[]}getRepositoryList(e,t,a){if(e){return e[`${this.props.showRegistry?this.props.account:a}/${t||""}`]||[]}return[]}getTags(e,t,a){let s=[];return this.props.specifyTagByRegex?e&&""===v(e)&&(e=void 0):t&&(s=t[a]||[],s.includes(e)||!e||e.includes("${")||(e=void 0)),{tag:e,tags:s}}componentWillReceiveProps(e){!this.images||["account","showRegistry"].some((t=>this.props[t]!==e[t]))?this.refreshImages(e):["organization","registry","repository"].some((t=>this.props[t]!==e[t]))&&this.updateThings(e),e.imageId&&e.imageId.includes("${")&&this.setState({defineManually:!0})}componentWillUnmount(){this.unmounted=!0}synchronizeChanges(e,t){const{organization:a,repository:s,tag:i,digest:n}=e;if(this.props.onChange){const e=R.generateImageId({organization:a,repository:s,tag:i,digest:n}),o={};i!==this.props.tag&&(o.tag=i),e!==this.props.imageId&&(o.imageId=e),a!==this.props.organization&&(o.organization=a),t!==this.props.registry&&(o.registry=t),s!==this.props.repository&&(o.repository=s),n!==this.props.digest&&(o.digest=n),Object.keys(o).length>0&&this.props.onChange(o)}}updateThings(e,t=!1){if(!this.repositoryMap||this.unmounted)return;const{imageId:a,specifyTagByRegex:s}=e;let{organization:i,registry:n,repository:o}=e;e.showRegistry&&(n=this.registryMap[e.account]);const r=!i||this.organizations.includes(i)||i.includes("${");r||(i="");const l=this.getRepositoryList(this.organizationMap,i,n),c=!o||o.includes("${")||l.includes(o);c||(o="");const{tag:g,tags:m}=this.getTags(e.tag,this.repositoryMap,o),p=g===e.tag||s,d={accountOptions:this.newAccounts.sort().map((e=>({label:e,value:e}))),organizationOptions:this.organizations.filter((e=>e)).sort().map((e=>({label:e,value:e}))),imagesLoaded:!0,repositoryOptions:l.sort().map((e=>({label:e,value:e}))),tagOptions:m.sort().map((e=>({label:e,value:e})))};if(!a||this.state.imagesLoaded&&!t||r&&c&&p)a&&a.includes("${")||this.synchronizeChanges(this.state.defineManually?R.splitImageId(a):{organization:i,repository:o,tag:g,digest:this.props.digest},n);else{d.defineManually=!0;const e=[];r||e.push("organization"),c||e.push("image"),p||e.push("tag"),d.missingFields=e,d.switchedManualWarning=`Could not find ${e.join(" or ")}, switched to manual entry`}this.setState(d)}initializeImages(e){if(this.state.imagesLoading)return;const{showRegistry:t,account:a,registry:s}=e,i={provider:"dockerRegistry",account:t?a:s};this.setState({imagesLoading:!0}),M.findImages(i).then((t=>{this.images=t,this.registryMap=this.getRegistryMap(this.images),this.accountMap=this.getAccountMap(this.images),this.newAccounts=this.accounts||Object.keys(this.accountMap),this.organizationMap=this.getOrganizationMap(this.images),this.repositoryMap=this.getRepositoryMap(this.images),this.organizations=this.getOrganizationsList(this.accountMap),this.updateThings(e,!0)})).finally((()=>{this.unmounted||this.setState({imagesLoading:!1})}))}refreshImages(e){this.initializeImages(e)}initializeAccounts(e){let{account:t}=e;a.listAccounts("dockerRegistry").then((a=>{const s=a.map((e=>e.name));this.props.showRegistry&&!t&&(t=s[0]),this.accounts=s,this.refreshImages({...e,account:t})}))}isNew(){const{account:e,organization:t,registry:a,repository:s,tag:i}=this.props;return!(e||t||a||s||i)}componentDidMount(){this.props.deferInitialization||!this.props.registry&&!this.isNew()||this.initializeAccounts(this.props)}valueChanged(e,t){const a={[e]:t};if($.some((t=>t===e))){const{organization:e,repository:t,tag:s,digest:i}=this.props,n={organization:e,repository:t,tag:s,digest:i,...a},o=R.generateImageId(n);a.imageId=o}this.props.onChange&&this.props.onChange(a)}render(){const{account:e,allowManualDefinition:t,digest:a,imageId:o,organization:r,repository:l,showDigest:c,showRegistry:g,specifyTagByRegex:m,tag:p}=this.props,{accountOptions:d,switchedManualWarning:u,missingFields:h,imagesLoading:f,lookupType:v,organizationOptions:y,repositoryOptions:N,defineManually:I,tagOptions:k}=this.state,C=R.splitImageId(o),z=E.createElement("div",{className:"sp-formItem groupHeader"},E.createElement("div",{className:"sp-formItem__left"},E.createElement("div",{className:"sp-formLabel"},"Define Image ID"),E.createElement("div",{className:"sp-formActions sp-formActions--mobile"},E.createElement("span",{className:"action"}))),E.createElement("div",{className:"sp-formItem__right"},E.createElement("div",{className:"sp-form"},E.createElement("span",{className:"field"},E.createElement(b,{value:I,disabled:f||!t,onChange:e=>this.showManualInput(e.value),options:A,clearable:!1}))))),_=u?E.createElement("div",{className:"sp-formItem"},E.createElement("div",{className:"sp-formItem__left"}),E.createElement("div",{className:"sp-formItem__right"},E.createElement(s,{type:"warning",message:E.createElement(E.Fragment,null,u,(h||[]).map((e=>E.createElement("div",{key:e},E.createElement(i,{expand:!0,id:`pipeline.config.docker.trigger.missing.${e}`})))))}))):null;if(I)return E.createElement("div",{className:"sp-formGroup"},z,E.createElement("div",{className:"sp-formItem"},E.createElement("div",{className:"sp-formItem__left"},E.createElement("div",{className:"sp-formLabel"},"Image ID"),E.createElement("div",{className:"sp-formActions sp-formActions--mobile"},E.createElement("span",{className:"action"}))),E.createElement("div",{className:"sp-formItem__right"},E.createElement("div",{className:"sp-form"},E.createElement("span",{className:"field"},E.createElement("input",{className:"form-control input-sm",value:o||"",onChange:e=>this.valueChanged("imageId",e.target.value)}))))),_);const w=g?E.createElement("div",{className:"sp-formItem"},E.createElement("div",{className:"sp-formItem__left"},E.createElement("div",{className:"sp-formLabel"},"Registry Name")),E.createElement("div",{className:"sp-formItem__right"},E.createElement("div",{className:"sp-form"},E.createElement("span",{className:"field"},E.createElement(b,{value:e,disabled:f,onChange:e=>this.valueChanged("account",e?e.value:""),options:d,isLoading:f})),E.createElement("span",{className:"sp-formActions sp-formActions--web"},E.createElement("span",{className:"action"},E.createElement(n,{value:f?"Images refreshing":"Refresh images list"},E.createElement("i",{className:"fa icon-button-refresh-arrows "+(f?"fa-spin":""),onClick:this.handleRefreshImages}))))))):null,L=E.createElement("div",{className:"sp-formItem"},E.createElement("div",{className:"sp-formItem__left"},E.createElement("div",{className:"sp-formLabel"},"Organization")),E.createElement("div",{className:"sp-formItem__right"},E.createElement("div",{className:"sp-form"},E.createElement("span",{className:"field"},r.includes("${")?E.createElement("input",{disabled:f,className:"form-control input-sm",value:r||"",onChange:e=>this.valueChanged("organization",e.target.value)}):E.createElement(b,{value:r||"",disabled:f,onChange:e=>this.valueChanged("organization",e&&e.value||""),placeholder:"No organization",options:y,isLoading:f}))))),M=E.createElement("div",{className:"sp-formItem"},E.createElement("div",{className:"sp-formItem__left"},E.createElement("div",{className:"sp-formLabel"},"Image")),E.createElement("div",{className:"sp-formItem__right"},E.createElement("div",{className:"sp-form"},E.createElement("span",{className:"field"},l.includes("${")?E.createElement("input",{className:"form-control input-sm",disabled:f,value:l||"",onChange:e=>this.valueChanged("repository",e.target.value)}):E.createElement(b,{value:l||"",disabled:f,onChange:e=>this.valueChanged("repository",e&&e.value||""),options:N,required:!0,isLoading:f}))))),x="tag"===v?m?E.createElement("div",{className:"sp-formItem"},E.createElement("div",{className:"sp-formItem__left"},E.createElement("div",{className:"sp-formLabel"},"Tag")),E.createElement("div",{className:"sp-formItem__right"},E.createElement("div",{className:"sp-form"},E.createElement("span",{className:"field"},E.createElement("input",{type:"text",className:"form-control input-sm",value:p||"",disabled:f||!l,onChange:e=>this.valueChanged("tag",e.target.value)}))),E.createElement(i,{id:"pipeline.config.docker.trigger.tag",expand:!0}))):E.createElement("div",{className:"sp-formItem"},E.createElement("div",{className:"sp-formItem__left"},E.createElement("div",{className:"sp-formLabel"},"Tag")),E.createElement("div",{className:"sp-formItem__right"},E.createElement("div",{className:"sp-form"},E.createElement("span",{className:"field"},p&&p.includes("${")?E.createElement("input",{className:"form-control input-sm",disabled:f,value:p||"",onChange:e=>this.valueChanged("tag",e.target.value),required:!0}):E.createElement(E.Fragment,null,E.createElement(b,{value:p||"",disabled:f||!l,isLoading:f,onChange:e=>this.valueChanged("tag",e?e.value:void 0),options:k,placeholder:"No tag",required:!0}),E.createElement(i,{id:"pipeline.config.docker.trigger.tag.additionalInfo",expand:!0})))))):null,T="digest"===v?E.createElement("div",{className:"sp-formItem"},E.createElement("div",{className:"sp-formItem__left"},E.createElement("div",{className:"sp-formLabel"},"Digest ",E.createElement(i,{id:"pipeline.config.docker.trigger.digest"}))),E.createElement("div",{className:"sp-formItem__right"},E.createElement("div",{className:"sp-form"},E.createElement("span",{className:"field"},E.createElement("input",{className:"form-control input-sm",placeholder:"sha256:abc123",value:a||C.digest||"",onChange:e=>this.valueChanged("digest",e.target.value),required:!0}))))):null,S=c?E.createElement("div",{className:"sp-formItem"},E.createElement("div",{className:"sp-formItem__left"},E.createElement("div",{className:"sp-formLabel"},"Type")),E.createElement("div",{className:"sp-formItem__right"},E.createElement("div",{className:"sp-form"},E.createElement("span",{className:"field"},E.createElement(b,{clearable:!1,value:v,options:[{value:"digest",label:"Digest"},{value:"tag",label:"Tag"}],onChange:this.lookupTypeChanged}))))):null;return E.createElement("div",{className:"sp-formGroup"},z,w,L,M,S,T,x)}}q.defaultProps={organization:"",registry:"",repository:"",showDigest:!0,allowManualDefinition:!0};const F=[{value:"digest",label:"Digest"},{value:"tag",label:"Tag"}];class B extends E.Component{constructor(e){super(e),this.queryStream=new C,this.handleQuery=()=>{const e=this.props.command.trigger;return"helm/oci"===e.type?z(M.findTags({provider:"dockerRegistry",account:e.account,repository:e.repository})):z(L.findTags({provider:"dockerRegistry",account:e.account,repository:e.repository}))},this.lookupTypeChanged=e=>{const t=e.value;this.updateArtifact(this.props.command,"tag"===t?this.state.selectedTag:this.state.digest),this.setState({lookupType:t})},this.updateSelectedTag=e=>{this.updateArtifact(this.props.command,e),this.setState({selectedTag:e}),this.props.command.triggerInvalid=!1},this.updateDigest=e=>{this.updateArtifact(this.props.command,e),this.setState({digest:e})},this.tagLoadSuccess=e=>{const{command:t}=this.props,a=t.trigger,s={};s.tags=e||[];const i=s.tags.find((e=>e===a.tag));i&&(s.selectedTag=i,this.updateSelectedTag(i)),s.tagsLoading=!1,this.setState(s)},this.tagLoadFailure=()=>{this.setState({tagsLoading:!1,loadError:!0})},this.initialize=()=>{const{command:e}=this.props;this.props.updateCommand("triggerInvalid",!0),this.props.updateCommand("extraFields",{tag:y(e,"extraFields.tag",""),artifacts:y(e,"extraFields.artifacts","")}),this.subscription&&this.subscription.unsubscribe(),"docker"!==e.trigger.type&&"helm/oci"!==e.trigger.type||(this.subscription=this.queryStream.pipe(_(250),w(this.handleQuery)).subscribe(this.tagLoadSuccess,this.tagLoadFailure),this.searchTags())},this.searchTags=(e="")=>{this.setState({tags:[`<span>Finding tags${e&&` matching ${e}`}...</span>`]}),this.queryStream.next()},this.state={digest:"",tags:[],tagsLoading:!0,loadError:!1,lookupType:"tag",selectedTag:""}}static formatLabel(e){return k.when(`(Docker Registry) ${e.account?e.account+":":""} ${e.repository||""}`)}updateArtifact(e,t){this.props.updateCommand("extraFields.tag",t);const a=e.trigger;if(a&&a.repository){let e="";a.registry&&(e+=a.registry+"/"),e+=a.repository;let s="";s="digest"===this.state.lookupType?`${e}@${t}`:`${e}:${t}`;const i="docker"===a.type?"docker/image":"helm/image";this.props.updateCommand("extraFields.artifacts",[{type:i,name:e,version:t,reference:s}])}}componentDidMount(){this.initialize()}componentWillUnmount(){this.subscription&&this.subscription.unsubscribe()}render(){const{digest:e,tags:t,tagsLoading:a,loadError:s,selectedTag:n,lookupType:o}=this.state,r=t.map((e=>({value:e})));return E.createElement(E.Fragment,null,E.createElement("div",{className:"form-group"},E.createElement("div",{className:"sm-label-right col-md-4"},"Type"),E.createElement("div",{className:"col-md-3"},E.createElement(m,{clearable:!1,value:o,options:F,onChange:this.lookupTypeChanged}))),"tag"===o&&E.createElement("div",{className:"form-group"},E.createElement("label",{className:"col-md-4 sm-label-right"},"Tag"),a&&E.createElement("div",{className:"col-md-6"},E.createElement("div",{className:"form-control-static text-center"},E.createElement(p,{size:"small"}))),s&&E.createElement("div",{className:"col-md-6"},"Error loading tags!"),!a&&E.createElement("div",{className:"col-md-6"},0===t.length&&E.createElement("div",null,E.createElement("p",{className:"form-control-static"},"No tags found")),t.length>0&&E.createElement(m,{options:r,optionRenderer:e=>E.createElement("span",null,e.value),clearable:!1,value:n,valueRenderer:e=>E.createElement("span",null,E.createElement("strong",null,e.value)),onChange:e=>this.updateSelectedTag(e.value),placeholder:"Search tags..."}))),"digest"===o&&E.createElement("div",{className:"form-group"},E.createElement("label",{className:"col-md-4 sm-label-right"},"Digest ",E.createElement(i,{id:"pipeline.config.docker.trigger.digest"})),E.createElement("div",{className:"col-md-6"},E.createElement("input",{value:e,onChange:e=>this.updateDigest(e.target.value),className:"form-control input-sm",required:!0}))))}}const W=e=>{const t=e.trigger;return E.createElement("li",null,t.repository,":",t.tag)};r.pipeline.registerTrigger({label:"Docker Registry",description:"Executes the pipeline on an image update",key:"docker",component:function(e){const{formik:t}=e,a=t.values;return E.createElement("div",{className:"form-horizontal"},E.createElement(S,{allowManualDefinition:!1,specifyTagByRegex:!0,account:a.account,organization:a.organization,registry:a.registry,repository:a.repository,tag:a.tag,showRegistry:!0,onChange:t=>{const{imageId:a,...s}=t;e.triggerUpdated(s)},showDigest:!1}))},manualExecutionComponent:B,executionStatusComponent:W,executionTriggerLabel:()=>"Docker Registry",validators:[{type:"requiredField",fieldName:"account",message:"<strong>Registry</strong> is a required field for Docker Registry triggers."},{type:"requiredField",fieldName:"repository",message:"<strong>Image</strong> is a required field for Docker Registry triggers."},{type:"serviceAccountAccess",preventSave:!0,message:"You do not have access to the service account configured in this pipeline's Docker Registry trigger.\n You will not be able to save your edits to this pipeline."}]}),r.pipeline.registerTrigger({label:"Helm Docker Registry",description:"Executes the pipeline on an helm/image update",key:"helm/oci",component:function(e){const{formik:t}=e,a=t.values;return E.createElement("div",{className:"form-horizontal"},E.createElement(q,{allowManualDefinition:!1,specifyTagByRegex:!0,account:a.account,organization:a.organization,registry:a.registry,repository:a.repository,tag:a.tag,showRegistry:!0,onChange:t=>{const{imageId:a,...s}=t;e.triggerUpdated(s)},showDigest:!1}))},manualExecutionComponent:B,executionStatusComponent:W,executionTriggerLabel:()=>"Helm Docker Registry",validators:[{type:"requiredField",fieldName:"account",message:"<strong>Registry</strong> is a required field for Docker Registry triggers."},{type:"requiredField",fieldName:"repository",message:"<strong>Image</strong> is a required field for Docker Registry triggers."},{type:"serviceAccountAccess",preventSave:!0,message:"You do not have access to the service account configured in this pipeline's Docker Registry trigger.\n You will not be able to save your edits to this pipeline."}]});const j="spinnaker.docker";N(j,[D]);export{j as DOCKER_MODULE,M as DockerChartImageReader,S as DockerImageAndTagSelector,L as DockerImageReader,R as DockerImageUtils};
1570
2
  //# sourceMappingURL=index.js.map