@spinnaker/kayenta 0.0.0-2025.1-0

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.
Files changed (289) hide show
  1. package/.editorconfig +9 -0
  2. package/.eslintrc.js +1 -0
  3. package/.huskyrc +5 -0
  4. package/.lintstagedrc.json +4 -0
  5. package/.prettierignore +4 -0
  6. package/.prettierrc.js +1 -0
  7. package/LICENSE.txt +203 -0
  8. package/README.md +81 -0
  9. package/__mocks__/styleMock.js +1 -0
  10. package/__mocks__/version.json +4 -0
  11. package/babel.config.js +3 -0
  12. package/build.gradle +67 -0
  13. package/build_scripts/checkLicenses.js +79 -0
  14. package/gradle.properties +0 -0
  15. package/jest.config.js +204 -0
  16. package/jest.setup.js +5 -0
  17. package/package.json +166 -0
  18. package/rollup-plugin-angularjs-template-loader.js +82 -0
  19. package/rollup.config.js +30 -0
  20. package/src/index.ts +2 -0
  21. package/src/kayenta/actions/creators.ts +163 -0
  22. package/src/kayenta/actions/index.ts +98 -0
  23. package/src/kayenta/canary.dataSource.bridge.ts +53 -0
  24. package/src/kayenta/canary.dataSource.stub.ts +64 -0
  25. package/src/kayenta/canary.help.ts +136 -0
  26. package/src/kayenta/canary.less +168 -0
  27. package/src/kayenta/canary.settings.ts +26 -0
  28. package/src/kayenta/canary.tsx +67 -0
  29. package/src/kayenta/components/canaryScore.component.less +77 -0
  30. package/src/kayenta/components/canaryScore.component.ts +12 -0
  31. package/src/kayenta/components/canaryScore.tsx +63 -0
  32. package/src/kayenta/components/canaryScores.component.ts +20 -0
  33. package/src/kayenta/components/canaryScores.less +22 -0
  34. package/src/kayenta/components/canaryScores.tsx +163 -0
  35. package/src/kayenta/components/loadStates.tsx +52 -0
  36. package/src/kayenta/domain/ICanaryConfig.ts +57 -0
  37. package/src/kayenta/domain/ICanaryConfigSummary.ts +7 -0
  38. package/src/kayenta/domain/ICanaryConfigUpdateResponse.ts +3 -0
  39. package/src/kayenta/domain/ICanaryExecutionStatusResult.ts +72 -0
  40. package/src/kayenta/domain/ICanaryJudgeResult.ts +51 -0
  41. package/src/kayenta/domain/ICanaryJudgeResultSummary.ts +5 -0
  42. package/src/kayenta/domain/ICanaryScoreThresholds.ts +4 -0
  43. package/src/kayenta/domain/IJudge.ts +5 -0
  44. package/src/kayenta/domain/IKayentaAccount.ts +14 -0
  45. package/src/kayenta/domain/IKayentaStageConfig.ts +58 -0
  46. package/src/kayenta/domain/IMetricSetPair.ts +17 -0
  47. package/src/kayenta/domain/IMetricsServiceMetadata.ts +2 -0
  48. package/src/kayenta/domain/ISetupCanaryStage.ts +11 -0
  49. package/src/kayenta/domain/MetricClassificationLabel.ts +8 -0
  50. package/src/kayenta/domain/ScoreClassificationLabel.ts +7 -0
  51. package/src/kayenta/domain/index.ts +15 -0
  52. package/src/kayenta/edit/changeMetricGroupModal.tsx +107 -0
  53. package/src/kayenta/edit/configDetail.tsx +31 -0
  54. package/src/kayenta/edit/configDetailActionButtons.tsx +24 -0
  55. package/src/kayenta/edit/configDetailHeader.tsx +104 -0
  56. package/src/kayenta/edit/configDetailLoadStates.tsx +36 -0
  57. package/src/kayenta/edit/configDetailLoader.tsx +60 -0
  58. package/src/kayenta/edit/configJson.less +42 -0
  59. package/src/kayenta/edit/configJsonModal.tsx +158 -0
  60. package/src/kayenta/edit/configList.less +7 -0
  61. package/src/kayenta/edit/configList.tsx +57 -0
  62. package/src/kayenta/edit/copyConfigButton.tsx +34 -0
  63. package/src/kayenta/edit/createConfigButton.tsx +34 -0
  64. package/src/kayenta/edit/deleteModal.tsx +87 -0
  65. package/src/kayenta/edit/edit.tsx +24 -0
  66. package/src/kayenta/edit/editMetricEffectSizes.tsx +186 -0
  67. package/src/kayenta/edit/editMetricModal.less +9 -0
  68. package/src/kayenta/edit/editMetricModal.spec.tsx +129 -0
  69. package/src/kayenta/edit/editMetricModal.tsx +294 -0
  70. package/src/kayenta/edit/editMetricValidation.spec.ts +63 -0
  71. package/src/kayenta/edit/editMetricValidation.ts +50 -0
  72. package/src/kayenta/edit/filterTemplateSelector.less +15 -0
  73. package/src/kayenta/edit/filterTemplateSelector.spec.tsx +106 -0
  74. package/src/kayenta/edit/filterTemplateSelector.tsx +194 -0
  75. package/src/kayenta/edit/filterTemplatesValidation.spec.ts +108 -0
  76. package/src/kayenta/edit/filterTemplatesValidation.ts +95 -0
  77. package/src/kayenta/edit/footer.less +30 -0
  78. package/src/kayenta/edit/footer.tsx +12 -0
  79. package/src/kayenta/edit/groupName.tsx +80 -0
  80. package/src/kayenta/edit/groupTabs.tsx +106 -0
  81. package/src/kayenta/edit/groupWeight.tsx +80 -0
  82. package/src/kayenta/edit/groupWeights.tsx +38 -0
  83. package/src/kayenta/edit/inlineTemplateEditor.spec.tsx +42 -0
  84. package/src/kayenta/edit/inlineTemplateEditor.tsx +61 -0
  85. package/src/kayenta/edit/judgeSelect.tsx +82 -0
  86. package/src/kayenta/edit/metricConfigurerDelegator.tsx +30 -0
  87. package/src/kayenta/edit/metricList.less +21 -0
  88. package/src/kayenta/edit/metricList.tsx +215 -0
  89. package/src/kayenta/edit/metricStoreSelector.tsx +66 -0
  90. package/src/kayenta/edit/nameAndDescription.tsx +90 -0
  91. package/src/kayenta/edit/openConfigJsonModalButton.tsx +33 -0
  92. package/src/kayenta/edit/openDeleteModalButton.tsx +50 -0
  93. package/src/kayenta/edit/ownedBy.tsx +34 -0
  94. package/src/kayenta/edit/save.tsx +19 -0
  95. package/src/kayenta/edit/saveConfigButton.tsx +65 -0
  96. package/src/kayenta/edit/saveConfigError.tsx +59 -0
  97. package/src/kayenta/edit/scoring.tsx +35 -0
  98. package/src/kayenta/edit/selectConfig.tsx +10 -0
  99. package/src/kayenta/edit/validationErrors.tsx +39 -0
  100. package/src/kayenta/index.ts +6 -0
  101. package/src/kayenta/layout/addNewButton.tsx +20 -0
  102. package/src/kayenta/layout/centeredDetail.tsx +13 -0
  103. package/src/kayenta/layout/deleteButton.tsx +11 -0
  104. package/src/kayenta/layout/disableable.tsx +87 -0
  105. package/src/kayenta/layout/formList.tsx +26 -0
  106. package/src/kayenta/layout/formRow.tsx +36 -0
  107. package/src/kayenta/layout/formattedDate.tsx +14 -0
  108. package/src/kayenta/layout/index.ts +2 -0
  109. package/src/kayenta/layout/keyValueList.less +20 -0
  110. package/src/kayenta/layout/keyValueList.tsx +114 -0
  111. package/src/kayenta/layout/list.less +9 -0
  112. package/src/kayenta/layout/list.spec.tsx +83 -0
  113. package/src/kayenta/layout/list.tsx +73 -0
  114. package/src/kayenta/layout/listDetail.tsx +33 -0
  115. package/src/kayenta/layout/radioChoice.tsx +29 -0
  116. package/src/kayenta/layout/styleguide.tsx +16 -0
  117. package/src/kayenta/layout/table/index.ts +5 -0
  118. package/src/kayenta/layout/table/nativeTable.tsx +51 -0
  119. package/src/kayenta/layout/table/nativeTableHeader.tsx +26 -0
  120. package/src/kayenta/layout/table/table.tsx +56 -0
  121. package/src/kayenta/layout/table/tableColumn.ts +7 -0
  122. package/src/kayenta/layout/table/tableHeader.tsx +23 -0
  123. package/src/kayenta/layout/tabs.tsx +26 -0
  124. package/src/kayenta/layout/titledSection.less +16 -0
  125. package/src/kayenta/layout/titledSection.tsx +20 -0
  126. package/src/kayenta/layout/titledSubsection.less +11 -0
  127. package/src/kayenta/layout/titledSubsection.tsx +22 -0
  128. package/src/kayenta/manualAnalysis/ManualAnalysisModal.tsx +716 -0
  129. package/src/kayenta/metricStore/atlas/atlasMetricConfigurer.tsx +130 -0
  130. package/src/kayenta/metricStore/atlas/index.ts +8 -0
  131. package/src/kayenta/metricStore/datadog/domain/IDatadogMetricDescriptor.ts +5 -0
  132. package/src/kayenta/metricStore/datadog/index.ts +9 -0
  133. package/src/kayenta/metricStore/datadog/metricConfigurer.tsx +90 -0
  134. package/src/kayenta/metricStore/datadog/metricTypeSelector.spec.tsx +59 -0
  135. package/src/kayenta/metricStore/datadog/metricTypeSelector.tsx +73 -0
  136. package/src/kayenta/metricStore/graphite/domain/IGraphiteMetricDescriptor.ts +5 -0
  137. package/src/kayenta/metricStore/graphite/index.ts +8 -0
  138. package/src/kayenta/metricStore/graphite/metricConfigurer.tsx +54 -0
  139. package/src/kayenta/metricStore/graphite/metricTypeSelector.tsx +80 -0
  140. package/src/kayenta/metricStore/graphite/typeahead.less +3 -0
  141. package/src/kayenta/metricStore/index.ts +8 -0
  142. package/src/kayenta/metricStore/metricStoreConfig.service.ts +12 -0
  143. package/src/kayenta/metricStore/newrelic/domain/INewRelicMetricDescriptor.ts +5 -0
  144. package/src/kayenta/metricStore/newrelic/index.ts +8 -0
  145. package/src/kayenta/metricStore/newrelic/metricConfigurer.tsx +58 -0
  146. package/src/kayenta/metricStore/prometheus/domain/IPrometheusCanaryMetricSetQueryConfig.ts +14 -0
  147. package/src/kayenta/metricStore/prometheus/domain/IPrometheusMetricDescriptor.ts +5 -0
  148. package/src/kayenta/metricStore/prometheus/index.ts +12 -0
  149. package/src/kayenta/metricStore/prometheus/metricConfigurer.tsx +157 -0
  150. package/src/kayenta/metricStore/prometheus/metricTypeSelector.less +5 -0
  151. package/src/kayenta/metricStore/prometheus/metricTypeSelector.spec.tsx +62 -0
  152. package/src/kayenta/metricStore/prometheus/metricTypeSelector.tsx +144 -0
  153. package/src/kayenta/metricStore/prometheus/queryTypeSelectors.spec.ts +61 -0
  154. package/src/kayenta/metricStore/prometheus/queryTypeSelectors.ts +38 -0
  155. package/src/kayenta/metricStore/signalfx/domain/ISignalFxCanaryMetricSetQueryConfig.ts +7 -0
  156. package/src/kayenta/metricStore/signalfx/index.ts +8 -0
  157. package/src/kayenta/metricStore/signalfx/metricConfigurer.less +10 -0
  158. package/src/kayenta/metricStore/signalfx/metricConfigurer.tsx +187 -0
  159. package/src/kayenta/metricStore/stackdriver/domain/IStackdriverCanaryMetricSetQueryConfig.ts +9 -0
  160. package/src/kayenta/metricStore/stackdriver/domain/IStackdriverMetricDescriptor.ts +17 -0
  161. package/src/kayenta/metricStore/stackdriver/index.ts +12 -0
  162. package/src/kayenta/metricStore/stackdriver/metricConfigurer.tsx +144 -0
  163. package/src/kayenta/metricStore/stackdriver/metricTypeSelector.spec.tsx +92 -0
  164. package/src/kayenta/metricStore/stackdriver/metricTypeSelector.tsx +113 -0
  165. package/src/kayenta/middleware/actionInterceptor.ts +29 -0
  166. package/src/kayenta/middleware/asyncDispatch.ts +37 -0
  167. package/src/kayenta/middleware/epics.ts +211 -0
  168. package/src/kayenta/middleware/index.ts +3 -0
  169. package/src/kayenta/navigation/canary.states.stub.ts +28 -0
  170. package/src/kayenta/navigation/canary.states.ts +182 -0
  171. package/src/kayenta/reducers/app.ts +56 -0
  172. package/src/kayenta/reducers/asyncRequest.ts +5 -0
  173. package/src/kayenta/reducers/data.ts +169 -0
  174. package/src/kayenta/reducers/editingTemplate.ts +54 -0
  175. package/src/kayenta/reducers/group.ts +82 -0
  176. package/src/kayenta/reducers/index.ts +245 -0
  177. package/src/kayenta/reducers/prometheusMetricConfig.spec.ts +33 -0
  178. package/src/kayenta/reducers/prometheusMetricConfig.ts +56 -0
  179. package/src/kayenta/reducers/selectedConfig.spec.ts +190 -0
  180. package/src/kayenta/reducers/selectedConfig.ts +566 -0
  181. package/src/kayenta/reducers/selectedRun.ts +101 -0
  182. package/src/kayenta/reducers/signalFxMetricConfig.ts +36 -0
  183. package/src/kayenta/reducers/stackdriverMetricConfig.spec.ts +33 -0
  184. package/src/kayenta/reducers/stackdriverMetricConfig.ts +41 -0
  185. package/src/kayenta/reducers/templates.spec.ts +192 -0
  186. package/src/kayenta/reducers/validators.ts +118 -0
  187. package/src/kayenta/report/detail/allMetricResultsHeader.tsx +32 -0
  188. package/src/kayenta/report/detail/clickableHeader.tsx +21 -0
  189. package/src/kayenta/report/detail/colors.ts +47 -0
  190. package/src/kayenta/report/detail/detail.less +16 -0
  191. package/src/kayenta/report/detail/detail.tsx +48 -0
  192. package/src/kayenta/report/detail/detailLoader.tsx +55 -0
  193. package/src/kayenta/report/detail/graph/graph.tsx +37 -0
  194. package/src/kayenta/report/detail/graph/metricSetPairGraph.service.ts +35 -0
  195. package/src/kayenta/report/detail/graph/semiotic/boxplot.less +45 -0
  196. package/src/kayenta/report/detail/graph/semiotic/boxplot.tsx +283 -0
  197. package/src/kayenta/report/detail/graph/semiotic/chartHeader.tsx +19 -0
  198. package/src/kayenta/report/detail/graph/semiotic/chartLegend.less +26 -0
  199. package/src/kayenta/report/detail/graph/semiotic/chartLegend.tsx +42 -0
  200. package/src/kayenta/report/detail/graph/semiotic/circleIcon.tsx +16 -0
  201. package/src/kayenta/report/detail/graph/semiotic/config.less +5 -0
  202. package/src/kayenta/report/detail/graph/semiotic/config.ts +38 -0
  203. package/src/kayenta/report/detail/graph/semiotic/customAxisTickLabel.tsx +17 -0
  204. package/src/kayenta/report/detail/graph/semiotic/declarations/labella.d.ts +16 -0
  205. package/src/kayenta/report/detail/graph/semiotic/declarations/react-container-dimensions.d.ts +3 -0
  206. package/src/kayenta/report/detail/graph/semiotic/declarations/semiotic.d.ts +160 -0
  207. package/src/kayenta/report/detail/graph/semiotic/differenceArea.less +17 -0
  208. package/src/kayenta/report/detail/graph/semiotic/differenceArea.tsx +186 -0
  209. package/src/kayenta/report/detail/graph/semiotic/histogram.less +22 -0
  210. package/src/kayenta/report/detail/graph/semiotic/histogram.tsx +251 -0
  211. package/src/kayenta/report/detail/graph/semiotic/index.tsx +19 -0
  212. package/src/kayenta/report/detail/graph/semiotic/noValidDataSign.less +5 -0
  213. package/src/kayenta/report/detail/graph/semiotic/noValidDataSign.tsx +10 -0
  214. package/src/kayenta/report/detail/graph/semiotic/secondaryTSXAxis.less +6 -0
  215. package/src/kayenta/report/detail/graph/semiotic/secondaryTSXAxis.tsx +58 -0
  216. package/src/kayenta/report/detail/graph/semiotic/semiotic.service.ts +32 -0
  217. package/src/kayenta/report/detail/graph/semiotic/semioticGraph.less +53 -0
  218. package/src/kayenta/report/detail/graph/semiotic/semioticGraph.tsx +49 -0
  219. package/src/kayenta/report/detail/graph/semiotic/timeSeries.less +42 -0
  220. package/src/kayenta/report/detail/graph/semiotic/timeSeries.tsx +473 -0
  221. package/src/kayenta/report/detail/graph/semiotic/tooltip.tsx +55 -0
  222. package/src/kayenta/report/detail/graph/semiotic/utils.ts +90 -0
  223. package/src/kayenta/report/detail/graphTypeSelector.less +4 -0
  224. package/src/kayenta/report/detail/graphTypeSelector.tsx +50 -0
  225. package/src/kayenta/report/detail/groupScores.tsx +68 -0
  226. package/src/kayenta/report/detail/header.less +70 -0
  227. package/src/kayenta/report/detail/header.tsx +39 -0
  228. package/src/kayenta/report/detail/headerArrow.tsx +13 -0
  229. package/src/kayenta/report/detail/loadStates.tsx +31 -0
  230. package/src/kayenta/report/detail/metricResultActions.less +29 -0
  231. package/src/kayenta/report/detail/metricResultActions.tsx +87 -0
  232. package/src/kayenta/report/detail/metricResultClassification.tsx +22 -0
  233. package/src/kayenta/report/detail/metricResultDetail.tsx +20 -0
  234. package/src/kayenta/report/detail/metricResultDetailLayout.tsx +19 -0
  235. package/src/kayenta/report/detail/metricResultDeviation.tsx +25 -0
  236. package/src/kayenta/report/detail/metricResultStats.less +9 -0
  237. package/src/kayenta/report/detail/metricResultStats.tsx +120 -0
  238. package/src/kayenta/report/detail/metricResults.less +12 -0
  239. package/src/kayenta/report/detail/metricResults.tsx +52 -0
  240. package/src/kayenta/report/detail/metricResultsClassificationFilters.tsx +65 -0
  241. package/src/kayenta/report/detail/metricResultsColumns.tsx +27 -0
  242. package/src/kayenta/report/detail/metricResultsList.less +44 -0
  243. package/src/kayenta/report/detail/metricResultsList.tsx +120 -0
  244. package/src/kayenta/report/detail/metricSetPairLoadStates.tsx +22 -0
  245. package/src/kayenta/report/detail/multipleResultsTable.tsx +81 -0
  246. package/src/kayenta/report/detail/reportException.tsx +57 -0
  247. package/src/kayenta/report/detail/reportExplanation.less +12 -0
  248. package/src/kayenta/report/detail/reportExplanation.tsx +32 -0
  249. package/src/kayenta/report/detail/reportMetadata.tsx +167 -0
  250. package/src/kayenta/report/detail/reportScores.less +47 -0
  251. package/src/kayenta/report/detail/reportScores.tsx +80 -0
  252. package/src/kayenta/report/detail/score.tsx +33 -0
  253. package/src/kayenta/report/detail/sourceLinks.tsx +69 -0
  254. package/src/kayenta/report/list/configLink.tsx +32 -0
  255. package/src/kayenta/report/list/executionList.less +7 -0
  256. package/src/kayenta/report/list/loadStates.tsx +32 -0
  257. package/src/kayenta/report/list/pipelineLink.tsx +15 -0
  258. package/src/kayenta/report/list/reportLink.tsx +33 -0
  259. package/src/kayenta/report/list/table.tsx +309 -0
  260. package/src/kayenta/report/report.tsx +11 -0
  261. package/src/kayenta/selectors/filterTemplatesSelectors.ts +87 -0
  262. package/src/kayenta/selectors/index.ts +62 -0
  263. package/src/kayenta/service/canaryConfig.service.ts +122 -0
  264. package/src/kayenta/service/canaryRun.service.ts +60 -0
  265. package/src/kayenta/service/delegateFactory.ts +24 -0
  266. package/src/kayenta/service/metricsServiceMetadata.service.ts +9 -0
  267. package/src/kayenta/stages/kayentaStage/AnalysisType.spec.tsx +47 -0
  268. package/src/kayenta/stages/kayentaStage/AnalysisType.tsx +49 -0
  269. package/src/kayenta/stages/kayentaStage/CanaryExecutionLabel.tsx +26 -0
  270. package/src/kayenta/stages/kayentaStage/analysisType.component.ts +12 -0
  271. package/src/kayenta/stages/kayentaStage/canaryRunSummaries.component.ts +12 -0
  272. package/src/kayenta/stages/kayentaStage/canaryRunSummaries.less +5 -0
  273. package/src/kayenta/stages/kayentaStage/canaryRunSummaries.tsx +136 -0
  274. package/src/kayenta/stages/kayentaStage/forAnalysisType.component.ts +45 -0
  275. package/src/kayenta/stages/kayentaStage/kayentaStage.controller.ts +789 -0
  276. package/src/kayenta/stages/kayentaStage/kayentaStage.html +528 -0
  277. package/src/kayenta/stages/kayentaStage/kayentaStage.less +5 -0
  278. package/src/kayenta/stages/kayentaStage/kayentaStage.transformer.ts +179 -0
  279. package/src/kayenta/stages/kayentaStage/kayentaStage.ts +221 -0
  280. package/src/kayenta/stages/kayentaStage/kayentaStageConfigSection.component.ts +21 -0
  281. package/src/kayenta/stages/kayentaStage/kayentaStageExecutionDetails.controller.ts +88 -0
  282. package/src/kayenta/stages/kayentaStage/kayentaStageExecutionDetails.html +114 -0
  283. package/src/kayenta/stages/kayentaStage/kayentaStageExecutionDetails.less +6 -0
  284. package/src/kayenta/stages/kayentaStage/stageTypes.ts +5 -0
  285. package/src/kayenta/utils/duration.spec.ts +69 -0
  286. package/src/kayenta/utils/duration.ts +48 -0
  287. package/src/lazy.ts +29 -0
  288. package/src/stub.ts +60 -0
  289. package/tsconfig.json +11 -0
@@ -0,0 +1,58 @@
1
+ export interface IKayentaStage {
2
+ canaryConfig: IKayentaStageCanaryConfig;
3
+ analysisType: KayentaAnalysisType;
4
+ deployments: IKayentaStageDeployments;
5
+ isNew: boolean;
6
+ }
7
+
8
+ export interface IKayentaStageCanaryConfig {
9
+ beginCanaryAnalysisAfterMins?: string;
10
+ canaryAnalysisIntervalMins: string;
11
+ canaryConfigId: string;
12
+ scopes: IKayentaStageCanaryConfigScope[];
13
+ combinedCanaryResultStrategy: string;
14
+ lifetimeHours?: string;
15
+ lifetimeDuration?: string; // String to be converted to Java.time.Duration in Orca (https://github.com/spinnaker/orca/blob/master/orca-kayenta/src/main/kotlin/com/netflix/spinnaker/orca/kayenta/model/KayentaCanaryContext.kt#L32)
16
+ lookbackMins?: string;
17
+ metricsAccountName: string;
18
+ scoreThresholds: {
19
+ pass: string;
20
+ marginal: string;
21
+ };
22
+ siteLocal?: { notificationEmail?: string[] | string };
23
+ storageAccountName: string;
24
+ }
25
+
26
+ export interface IKayentaStageCanaryConfigScope {
27
+ scopeName: string;
28
+ controlScope?: string;
29
+ controlLocation?: string;
30
+ experimentScope?: string;
31
+ experimentLocation?: string;
32
+ startTimeIso?: string;
33
+ endTimeIso?: string;
34
+ step?: number;
35
+ extendedScopeParams: { [key: string]: string };
36
+ }
37
+
38
+ export interface IKayentaStageDeployments {
39
+ baseline: {
40
+ cloudProvider: string;
41
+ application: string;
42
+ account: string;
43
+ cluster: string;
44
+ };
45
+ serverGroupPairs: IKayentaServerGroupPair[];
46
+ delayBeforeCleanup: string; // String to be converted to Java.time.Duration in Orca (https://github.com/spinnaker/orca/blob/master/orca-kayenta/src/main/kotlin/com/netflix/spinnaker/orca/kayenta/model/Deployments.kt#L33)
47
+ }
48
+
49
+ export interface IKayentaServerGroupPair {
50
+ control: any;
51
+ experiment: any;
52
+ }
53
+
54
+ export enum KayentaAnalysisType {
55
+ RealTimeAutomatic = 'realTimeAutomatic',
56
+ RealTime = 'realTime',
57
+ Retrospective = 'retrospective',
58
+ }
@@ -0,0 +1,17 @@
1
+ export interface IMetricSetPair {
2
+ name: string;
3
+ id: string;
4
+ tags: { [key: string]: string };
5
+ attributes: {
6
+ control: { [key: string]: string };
7
+ experiment: { [key: string]: string };
8
+ };
9
+ values: { [key: string]: number[] };
10
+ scopes: { [key: string]: IMetricSetScope };
11
+ }
12
+
13
+ export interface IMetricSetScope {
14
+ startTimeIso: string;
15
+ startTimeMillis: number;
16
+ stepMillis: number;
17
+ }
@@ -0,0 +1,2 @@
1
+ // Marker for metric descriptor metadata.
2
+ export interface IMetricsServiceMetadata {}
@@ -0,0 +1,11 @@
1
+ import { IExecutionStage } from '@spinnaker/core';
2
+ import { ICanaryConfig } from './ICanaryConfig';
3
+
4
+ export interface ISetupCanaryStage extends IExecutionStage {
5
+ context: {
6
+ canaryConfigId: string;
7
+ };
8
+ outputs: {
9
+ canaryConfig: ICanaryConfig;
10
+ };
11
+ }
@@ -0,0 +1,8 @@
1
+ export enum MetricClassificationLabel {
2
+ Pass = 'Pass',
3
+ High = 'High',
4
+ Low = 'Low',
5
+ Nodata = 'Nodata',
6
+ NodataFailMetric = 'NodataFailMetric',
7
+ Error = 'Error',
8
+ }
@@ -0,0 +1,7 @@
1
+ export enum ScoreClassificationLabel {
2
+ Pass = 'Pass',
3
+ Marginal = 'Marginal',
4
+ Fail = 'Fail',
5
+ Nodata = 'Nodata',
6
+ Error = 'Error',
7
+ }
@@ -0,0 +1,15 @@
1
+ export * from './ICanaryConfig';
2
+ export * from './ICanaryScoreThresholds';
3
+ export * from './ICanaryConfigSummary';
4
+ export * from './ICanaryJudgeResult';
5
+ export * from './ICanaryJudgeResultSummary';
6
+ export * from './IJudge';
7
+ export * from './IKayentaAccount';
8
+ export * from './IMetricSetPair';
9
+ export * from './ISetupCanaryStage';
10
+ export * from './ICanaryExecutionStatusResult';
11
+ export * from './IMetricsServiceMetadata';
12
+ export * from './ICanaryConfigUpdateResponse';
13
+ export * from './IKayentaStageConfig';
14
+ export * from './MetricClassificationLabel';
15
+ export * from './ScoreClassificationLabel';
@@ -0,0 +1,107 @@
1
+ import * as Creators from 'kayenta/actions/creators';
2
+ import { CanarySettings } from 'kayenta/canary.settings';
3
+ import { ICanaryMetricConfig } from 'kayenta/domain/ICanaryConfig';
4
+ import { DISABLE_EDIT_CONFIG, DisableableSelect } from 'kayenta/layout/disableable';
5
+ import Styleguide from 'kayenta/layout/styleguide';
6
+ import { ICanaryState } from 'kayenta/reducers';
7
+ import * as React from 'react';
8
+ import { Modal } from 'react-bootstrap';
9
+ import { connect } from 'react-redux';
10
+ import { Action } from 'redux';
11
+
12
+ import { noop } from '@spinnaker/core';
13
+
14
+ interface IChangeMetricGroupModalOwnProps {
15
+ metric: ICanaryMetricConfig;
16
+ }
17
+
18
+ interface IChangeMetricGroupModalStateProps {
19
+ groups: string[];
20
+ toGroup: string;
21
+ }
22
+
23
+ interface IChangeMetricGroupModalDispatchProps {
24
+ select: (event: any) => void;
25
+ clear: () => void;
26
+ confirm: () => void;
27
+ }
28
+
29
+ function ChangeMetricGroupModal({
30
+ groups,
31
+ toGroup,
32
+ confirm,
33
+ clear,
34
+ select,
35
+ }: IChangeMetricGroupModalStateProps & IChangeMetricGroupModalDispatchProps) {
36
+ return (
37
+ <Modal show={true} onHide={noop}>
38
+ <Styleguide>
39
+ <Modal.Header>
40
+ <Modal.Title>Change Metric Group</Modal.Title>
41
+ </Modal.Header>
42
+ <Modal.Body>
43
+ <DisableableSelect
44
+ value={toGroup || ''}
45
+ onChange={select}
46
+ className="form-control input-sm"
47
+ disabled={CanarySettings.disableConfigEdit}
48
+ disabledStateKeys={[DISABLE_EDIT_CONFIG]}
49
+ >
50
+ <option value={''}>-- select group --</option>
51
+ {groups.map((g) => (
52
+ <option key={g} value={g}>
53
+ {g}
54
+ </option>
55
+ ))}
56
+ </DisableableSelect>
57
+ </Modal.Body>
58
+ <Modal.Footer>
59
+ <ul className="list-inline pull-right">
60
+ <li>
61
+ <button className="passive" onClick={clear}>
62
+ Cancel
63
+ </button>
64
+ </li>
65
+ <li>
66
+ <button className="primary" disabled={!toGroup} onClick={confirm}>
67
+ OK
68
+ </button>
69
+ </li>
70
+ </ul>
71
+ </Modal.Footer>
72
+ </Styleguide>
73
+ </Modal>
74
+ );
75
+ }
76
+
77
+ function mapStateToProps(
78
+ state: ICanaryState,
79
+ { metric }: IChangeMetricGroupModalOwnProps,
80
+ ): IChangeMetricGroupModalStateProps {
81
+ // If a metric belongs to more than one group, allow a move into one of those groups.
82
+ // e.g., a [system, requests] -> [requests] move should be allowed, but
83
+ // don't offer a [system] -> [system] move.
84
+ return {
85
+ groups: state.selectedConfig.group.list.filter((g) => metric.groups.length > 1 || !metric.groups.includes(g)),
86
+ toGroup: state.selectedConfig.changeMetricGroup.toGroup,
87
+ };
88
+ }
89
+
90
+ function mapDispatchToProps(
91
+ dispatch: (action: Action & any) => void,
92
+ { metric }: IChangeMetricGroupModalOwnProps,
93
+ ): IChangeMetricGroupModalDispatchProps {
94
+ return {
95
+ select: (event: any) => {
96
+ dispatch(Creators.changeMetricGroupSelect({ group: event.target.value || null }));
97
+ },
98
+ clear: () => {
99
+ dispatch(Creators.changeMetricGroupConfirm({ metricId: null }));
100
+ },
101
+ confirm: () => {
102
+ dispatch(Creators.changeMetricGroupConfirm({ metricId: metric.id }));
103
+ },
104
+ };
105
+ }
106
+
107
+ export default connect(mapStateToProps, mapDispatchToProps)(ChangeMetricGroupModal);
@@ -0,0 +1,31 @@
1
+ import * as React from 'react';
2
+
3
+ import ConfigDetailHeader from './configDetailHeader';
4
+ import EditMetricModal from './editMetricModal';
5
+ import GroupTabs from './groupTabs';
6
+ import TitledSection from '../layout/titledSection';
7
+ import MetricList from './metricList';
8
+ import NameAndDescription from './nameAndDescription';
9
+ import Scoring from './scoring';
10
+
11
+ /*
12
+ * Top-level config detail layout
13
+ */
14
+ export default function ConfigDetail() {
15
+ return (
16
+ <section className="config-detail">
17
+ <ConfigDetailHeader />
18
+ <TitledSection title="Name and Description">
19
+ <NameAndDescription />
20
+ </TitledSection>
21
+ <TitledSection title="Metrics">
22
+ <GroupTabs />
23
+ <MetricList />
24
+ <EditMetricModal />
25
+ </TitledSection>
26
+ <TitledSection title="Scoring">
27
+ <Scoring />
28
+ </TitledSection>
29
+ </section>
30
+ );
31
+ }
@@ -0,0 +1,24 @@
1
+ import * as React from 'react';
2
+
3
+ import CopyConfigButton from './copyConfigButton';
4
+ import OpenEditConfigJsonModalButton from './openConfigJsonModalButton';
5
+ import OpenDeleteModalButton from './openDeleteModalButton';
6
+
7
+ /*
8
+ * Layout for canary config action buttons.
9
+ */
10
+ export default function ConfigDetailActionButtons() {
11
+ return (
12
+ <ul className="list-inline pull-right">
13
+ <li>
14
+ <OpenEditConfigJsonModalButton />
15
+ </li>
16
+ <li>
17
+ <CopyConfigButton />
18
+ </li>
19
+ <li>
20
+ <OpenDeleteModalButton />
21
+ </li>
22
+ </ul>
23
+ );
24
+ }
@@ -0,0 +1,104 @@
1
+ import { UISref } from '@uirouter/react';
2
+ import { CanarySettings } from 'kayenta/canary.settings';
3
+ import { ICanaryConfig } from 'kayenta/domain';
4
+ import FormattedDate from 'kayenta/layout/formattedDate';
5
+ import { ICanaryState } from 'kayenta/reducers';
6
+ import { mapStateToConfig } from 'kayenta/service/canaryConfig.service';
7
+ import * as React from 'react';
8
+ import { connect } from 'react-redux';
9
+
10
+ import ConfigDetailActionButtons from './configDetailActionButtons';
11
+
12
+ interface IConfigDetailStateProps {
13
+ selectedConfig: ICanaryConfig;
14
+ editingDisabled: boolean;
15
+ disableConfigEdit: boolean;
16
+ }
17
+
18
+ const getOwnerAppLinks = (owners: string[]) => {
19
+ if (owners.length === 1) {
20
+ return (
21
+ <UISref to="." params={{ application: owners[0] }}>
22
+ <a>{owners[0]}</a>
23
+ </UISref>
24
+ );
25
+ } else {
26
+ // totally gross to read, but a somewhat-straightforward way of creating
27
+ // a 'one, two, or three' sentence from this array of app names with some JSX in between
28
+ const lastIndex = owners.length - 1;
29
+ return owners.map((owner, index) => (
30
+ <React.Fragment key={owner}>
31
+ {index === lastIndex ? 'or ' : ''}
32
+ <UISref to="." params={{ application: owner }}>
33
+ <a>{owner}</a>
34
+ </UISref>
35
+ {index < lastIndex && owners.length === 2 ? ' ' : ''}
36
+ {index < lastIndex && owners.length > 2 ? ', ' : ''}
37
+ </React.Fragment>
38
+ ));
39
+ }
40
+ };
41
+
42
+ const EditingDisabledWarning = ({ owners }: { owners: string[] }) => {
43
+ return (
44
+ <div className="horizontal middle well-compact alert alert-warning config-detail-edit-warning">
45
+ <i className="fa fa-exclamation-triangle sp-margin-m-right" />
46
+ <span>
47
+ <b>
48
+ Editing is disabled because this config is owned by{' '}
49
+ {owners.length > 1 ? `${owners.length} other applications` : 'another application'}.
50
+ </b>{' '}
51
+ To edit, view in {getOwnerAppLinks(owners)}
52
+ </span>
53
+ </div>
54
+ );
55
+ };
56
+
57
+ const ConfigEditingDisabledWarning = () => {
58
+ return (
59
+ <div className="horizontal middle well-compact alert alert-warning config-detail-edit-warning">
60
+ <i className="fa fa-exclamation-triangle sp-margin-m-right" />
61
+ <span>
62
+ <b>Canary config is locked and does not allow modification</b>
63
+ </span>
64
+ </div>
65
+ );
66
+ };
67
+
68
+ /*
69
+ * Config detail header layout.
70
+ */
71
+ function ConfigDetailHeader({ selectedConfig, editingDisabled, disableConfigEdit }: IConfigDetailStateProps) {
72
+ return (
73
+ <div className="vertical">
74
+ <div className="horizontal config-detail-header">
75
+ <div className="flex-3">
76
+ <h1 className="heading-1 color-text-primary">{selectedConfig ? selectedConfig.name : ''}</h1>
77
+ </div>
78
+ <div className="flex-1">
79
+ <h5 className="heading-5">
80
+ <strong>Edited:</strong>{' '}
81
+ <FormattedDate dateIso={selectedConfig ? selectedConfig.updatedTimestampIso : ''} />
82
+ </h5>
83
+ </div>
84
+ <div className="flex-2">
85
+ <ConfigDetailActionButtons />
86
+ </div>
87
+ </div>
88
+ {selectedConfig && editingDisabled && !disableConfigEdit && (
89
+ <EditingDisabledWarning owners={selectedConfig.applications} />
90
+ )}
91
+ {selectedConfig && disableConfigEdit && <ConfigEditingDisabledWarning />}
92
+ </div>
93
+ );
94
+ }
95
+
96
+ function mapStateToProps(state: ICanaryState): IConfigDetailStateProps {
97
+ return {
98
+ selectedConfig: mapStateToConfig(state),
99
+ editingDisabled: state.app.disableConfigEdit,
100
+ disableConfigEdit: CanarySettings.disableConfigEdit,
101
+ };
102
+ }
103
+
104
+ export default connect(mapStateToProps)(ConfigDetailHeader);
@@ -0,0 +1,36 @@
1
+ import LoadStatesBuilder from 'kayenta/components/loadStates';
2
+ import * as React from 'react';
3
+ import { connect } from 'react-redux';
4
+
5
+ import ConfigDetail from './configDetail';
6
+ import CenteredDetail from '../layout/centeredDetail';
7
+ import { AsyncRequestState } from '../reducers/asyncRequest';
8
+ import { ICanaryState } from '../reducers/index';
9
+
10
+ interface IConfigLoadStatesProps {
11
+ configLoadState: AsyncRequestState;
12
+ }
13
+
14
+ /*
15
+ * Renders appropriate view given the configuration detail's load state.
16
+ */
17
+ function ConfigDetailLoadStates({ configLoadState }: IConfigLoadStatesProps) {
18
+ const LoadStates = new LoadStatesBuilder()
19
+ .onFulfilled(<ConfigDetail />)
20
+ .onFailed(
21
+ <CenteredDetail>
22
+ <h3 className="heading-3">Could not load canary config.</h3>
23
+ </CenteredDetail>,
24
+ )
25
+ .build();
26
+
27
+ return <LoadStates state={configLoadState} />;
28
+ }
29
+
30
+ function mapStateToProps(state: ICanaryState): IConfigLoadStatesProps {
31
+ return {
32
+ configLoadState: state.selectedConfig.load.state,
33
+ };
34
+ }
35
+
36
+ export default connect(mapStateToProps)(ConfigDetailLoadStates);
@@ -0,0 +1,60 @@
1
+ import * as React from 'react';
2
+ import { connect } from 'react-redux';
3
+ import { Action } from 'redux';
4
+ import { Observable } from 'rxjs/Observable';
5
+ import { Subscription } from 'rxjs/Subscription';
6
+
7
+ import * as Creators from '../actions/creators';
8
+ import ConfigDetailLoadStates from './configDetailLoadStates';
9
+
10
+ interface IConfigLoaderStateParamsProps {
11
+ configNameStream: Observable<IConfigDetailStateParams>;
12
+ }
13
+
14
+ interface IConfigLoaderDispatchProps {
15
+ loadConfig: (stateParams: IConfigDetailStateParams) => void;
16
+ }
17
+
18
+ interface IConfigDetailStateParams {
19
+ id: string;
20
+ copy: boolean;
21
+ new: boolean;
22
+ }
23
+
24
+ /*
25
+ * Top-level .configDetail state component.
26
+ * Loads config details on changes to /canary/:configName path parameter, renders load states.
27
+ */
28
+ class ConfigDetailLoader extends React.Component<IConfigLoaderDispatchProps & IConfigLoaderStateParamsProps> {
29
+ private subscription: Subscription;
30
+
31
+ constructor(props: IConfigLoaderDispatchProps & IConfigLoaderStateParamsProps) {
32
+ const { configNameStream, loadConfig } = props;
33
+ super(props);
34
+ this.subscription = configNameStream.subscribe(loadConfig);
35
+ }
36
+
37
+ public componentWillUnmount(): void {
38
+ this.subscription.unsubscribe();
39
+ }
40
+
41
+ public render() {
42
+ return <ConfigDetailLoadStates />;
43
+ }
44
+ }
45
+
46
+ function mapDispatchToProps(dispatch: (action: Action & any) => void): IConfigLoaderDispatchProps {
47
+ return {
48
+ loadConfig: (stateParams: IConfigDetailStateParams) => {
49
+ if (stateParams.copy) {
50
+ dispatch(Creators.copySelectedConfig());
51
+ } else if (stateParams.new) {
52
+ dispatch(Creators.createNewConfig());
53
+ } else if (stateParams.id) {
54
+ dispatch(Creators.loadConfigRequest({ id: stateParams.id }));
55
+ }
56
+ },
57
+ };
58
+ }
59
+
60
+ export default connect(null, mapDispatchToProps)(ConfigDetailLoader);
@@ -0,0 +1,42 @@
1
+ .ace-editor {
2
+ div,
3
+ span {
4
+ font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;
5
+ }
6
+
7
+ > div.ace_gutter {
8
+ z-index: 0;
9
+ }
10
+ }
11
+
12
+ .kayenta-config-json {
13
+ textarea {
14
+ height: 65vh;
15
+ overflow: scroll;
16
+ padding: 2px 6px;
17
+ line-height: 1.4rem;
18
+ font-family: monospace;
19
+ font-size: 1rem;
20
+ }
21
+
22
+ pre.diff {
23
+ height: 65vh;
24
+ box-shadow: none;
25
+ width: 100%;
26
+ padding: 0;
27
+ .match,
28
+ .add,
29
+ .remove {
30
+ font-family: monospace;
31
+ font-size: 1rem;
32
+ }
33
+ }
34
+
35
+ .modal-show-history {
36
+ .show-history {
37
+ .summary-nav {
38
+ right: 7px;
39
+ }
40
+ }
41
+ }
42
+ }