@spinnaker/ecs 0.0.0-main-2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1186 -0
- package/LICENSE.txt +203 -0
- package/dist/common/common.module.d.ts +1 -0
- package/dist/common/footer.component.d.ts +1 -0
- package/dist/domain/IEcsLoadBalancer.d.ts +119 -0
- package/dist/ecs.help.d.ts +1 -0
- package/dist/ecs.module.d.ts +4 -0
- package/dist/ecs.settings.d.ts +9 -0
- package/dist/ecsCluster/IEcsCapacityProviderDetails.d.ts +10 -0
- package/dist/ecsCluster/IEcsCluster.d.ts +5 -0
- package/dist/ecsCluster/ecsCluster.read.service.d.ts +7 -0
- package/dist/iamRoles/IRole.d.ts +6 -0
- package/dist/iamRoles/iamRole.read.service.d.ts +5 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +6010 -0
- package/dist/index.js.map +1 -0
- package/dist/instance/details/instance.details.controller.d.ts +2 -0
- package/dist/loadBalancer/EcsLoadBalancerClusterContainer.d.ts +6 -0
- package/dist/loadBalancer/TargetGroup.d.ts +11 -0
- package/dist/loadBalancer/details/loadBalancerDetails.d.ts +27 -0
- package/dist/loadBalancer/details/targetGroupDetails.d.ts +30 -0
- package/dist/loadBalancer/listener.d.ts +10 -0
- package/dist/loadBalancer/loadBalancer.transformer.d.ts +8 -0
- package/dist/loadBalancer/targetGroup.states.d.ts +1 -0
- package/dist/metricAlarm/MetricAlarm.d.ts +6 -0
- package/dist/metricAlarm/metricAlarm.read.service.d.ts +5 -0
- package/dist/pipeline/stages/destroyAsg/ecsDestroyAsgStage.d.ts +2 -0
- package/dist/pipeline/stages/disableAsg/ecsDisableAsgStage.d.ts +2 -0
- package/dist/pipeline/stages/disableCluster/ecsDisableClusterStage.d.ts +2 -0
- package/dist/pipeline/stages/enableAsg/ecsEnableAsgStage.d.ts +2 -0
- package/dist/pipeline/stages/findImageFromTags/ecsFindImageFromTagStage.d.ts +2 -0
- package/dist/pipeline/stages/resizeAsg/ecsResizeAsgStage.d.ts +2 -0
- package/dist/pipeline/stages/scaleDownCluster/ecsScaleDownClusterStage.d.ts +2 -0
- package/dist/pipeline/stages/shrinkCluster/ecsShrinkClusterStage.d.ts +2 -0
- package/dist/placementStrategy/IPlacementStrategy.d.ts +4 -0
- package/dist/placementStrategy/placementStrategy.service.d.ts +11 -0
- package/dist/secrets/ISecret.d.ts +5 -0
- package/dist/secrets/secret.read.service.d.ts +5 -0
- package/dist/securityGroup/details/securityGroupDetail.controller.d.ts +2 -0
- package/dist/securityGroup/securityGroup.module.d.ts +1 -0
- package/dist/securityGroup/securityGroup.reader.d.ts +5 -0
- package/dist/securityGroup/securityGroup.transformer.d.ts +2 -0
- package/dist/serverGroup/configure/serverGroupCommandBuilder.service.d.ts +2 -0
- package/dist/serverGroup/configure/serverGroupConfiguration.service.d.ts +165 -0
- package/dist/serverGroup/configure/wizard/CloneServerGroup.ecs.controller.d.ts +2 -0
- package/dist/serverGroup/configure/wizard/advancedSettings/advancedSettings.component.d.ts +2 -0
- package/dist/serverGroup/configure/wizard/capacityProvider/CapacityProvider.d.ts +7 -0
- package/dist/serverGroup/configure/wizard/container/Container.d.ts +32 -0
- package/dist/serverGroup/configure/wizard/horizontalScaling/horizontalScaling.component.d.ts +2 -0
- package/dist/serverGroup/configure/wizard/location/ServerGroupBasicSettings.controller.d.ts +2 -0
- package/dist/serverGroup/configure/wizard/logging/logging.component.d.ts +1 -0
- package/dist/serverGroup/configure/wizard/networking/Networking.d.ts +28 -0
- package/dist/serverGroup/configure/wizard/serviceDiscovery/ServiceDiscovery.d.ts +34 -0
- package/dist/serverGroup/configure/wizard/taskDefinition/TaskDefinition.d.ts +39 -0
- package/dist/serverGroup/details/resize/resizeCapacity.component.d.ts +1 -0
- package/dist/serverGroup/details/resize/resizeServerGroup.controller.d.ts +2 -0
- package/dist/serverGroup/details/rollback/rollbackServerGroup.controller.d.ts +2 -0
- package/dist/serverGroup/details/serverGroupDetails.ecs.controller.d.ts +2 -0
- package/dist/serverGroup/details/serverGroupDetails.module.d.ts +1 -0
- package/dist/serverGroup/events/EventsLink.d.ts +4 -0
- package/dist/serverGroup/events/events.component.d.ts +3 -0
- package/dist/serverGroup/events/events.controller.d.ts +19 -0
- package/dist/serverGroup/events/serverGroupEventsReader.service.d.ts +10 -0
- package/dist/serverGroup/serverGroup.module.d.ts +1 -0
- package/dist/serverGroup/serverGroup.transformer.d.ts +11 -0
- package/dist/serviceDiscovery/IServiceDiscovery.d.ts +12 -0
- package/dist/serviceDiscovery/serviceDiscovery.read.service.d.ts +4 -0
- package/package.json +47 -0
- package/src/common/common.module.ts +6 -0
- package/src/common/footer.component.ts +29 -0
- package/src/domain/IEcsLoadBalancer.ts +129 -0
- package/src/ecs.help.ts +91 -0
- package/src/ecs.module.ts +116 -0
- package/src/ecs.settings.ts +17 -0
- package/src/ecsCluster/IEcsCapacityProviderDetails.ts +11 -0
- package/src/ecsCluster/IEcsCluster.ts +5 -0
- package/src/ecsCluster/ecsCluster.read.service.ts +23 -0
- package/src/iamRoles/IRole.ts +6 -0
- package/src/iamRoles/iamRole.read.service.ts +14 -0
- package/src/index.ts +1 -0
- package/src/instance/details/instance.details.controller.js +356 -0
- package/src/instance/details/instanceDetails.html +204 -0
- package/src/loadBalancer/EcsLoadBalancerClusterContainer.tsx +48 -0
- package/src/loadBalancer/TargetGroup.tsx +74 -0
- package/src/loadBalancer/details/loadBalancerDetails.tsx +235 -0
- package/src/loadBalancer/details/targetGroupDetails.tsx +251 -0
- package/src/loadBalancer/listener.tsx +65 -0
- package/src/loadBalancer/loadBalancer.transformer.ts +21 -0
- package/src/loadBalancer/targetGroup.states.ts +59 -0
- package/src/logo/ecs.icon.svg +27 -0
- package/src/logo/ecs.logo.less +5 -0
- package/src/logo/ecs.logo.svg +27 -0
- package/src/metricAlarm/MetricAlarm.ts +6 -0
- package/src/metricAlarm/metricAlarm.read.service.ts +14 -0
- package/src/pipeline/stages/cloneServerGroup/cloneServerGroupStage.html +101 -0
- package/src/pipeline/stages/cloneServerGroup/cloneServerGroupStepLabel.html +1 -0
- package/src/pipeline/stages/cloneServerGroup/ecsCloneServerGroupStage.js +94 -0
- package/src/pipeline/stages/destroyAsg/destroyAsgStage.html +9 -0
- package/src/pipeline/stages/destroyAsg/destroyAsgStepLabel.html +1 -0
- package/src/pipeline/stages/destroyAsg/ecsDestroyAsgStage.js +65 -0
- package/src/pipeline/stages/disableAsg/disableAsgStage.html +11 -0
- package/src/pipeline/stages/disableAsg/disableAsgStepLabel.html +1 -0
- package/src/pipeline/stages/disableAsg/ecsDisableAsgStage.js +70 -0
- package/src/pipeline/stages/disableCluster/disableClusterStage.html +26 -0
- package/src/pipeline/stages/disableCluster/ecsDisableClusterStage.js +84 -0
- package/src/pipeline/stages/enableAsg/ecsEnableAsgStage.js +73 -0
- package/src/pipeline/stages/enableAsg/enableAsgStage.html +11 -0
- package/src/pipeline/stages/enableAsg/enableAsgStepLabel.html +1 -0
- package/src/pipeline/stages/findImageFromTags/ecsFindImageFromTagStage.js +26 -0
- package/src/pipeline/stages/findImageFromTags/findImageFromTagsExecutionDetails.html +36 -0
- package/src/pipeline/stages/findImageFromTags/findImageFromTagsStage.html +9 -0
- package/src/pipeline/stages/resizeAsg/ecsResizeAsgStage.js +128 -0
- package/src/pipeline/stages/resizeAsg/resizeAsgStage.html +87 -0
- package/src/pipeline/stages/resizeAsg/resizeAsgStepLabel.html +1 -0
- package/src/pipeline/stages/scaleDownCluster/ecsScaleDownClusterStage.js +78 -0
- package/src/pipeline/stages/scaleDownCluster/scaleDownClusterStage.html +35 -0
- package/src/pipeline/stages/shrinkCluster/ecsShrinkClusterStage.js +73 -0
- package/src/pipeline/stages/shrinkCluster/shrinkClusterStage.html +34 -0
- package/src/placementStrategy/IPlacementStrategy.ts +4 -0
- package/src/placementStrategy/placementStrategy.service.ts +63 -0
- package/src/secrets/ISecret.ts +5 -0
- package/src/secrets/secret.read.service.ts +14 -0
- package/src/securityGroup/details/securityGroupDetail.controller.js +147 -0
- package/src/securityGroup/details/securityGroupDetail.html +104 -0
- package/src/securityGroup/securityGroup.module.ts +12 -0
- package/src/securityGroup/securityGroup.reader.ts +16 -0
- package/src/securityGroup/securityGroup.transformer.js +13 -0
- package/src/serverGroup/configure/serverGroupCommandBuilder.service.js +281 -0
- package/src/serverGroup/configure/serverGroupConfiguration.service.ts +747 -0
- package/src/serverGroup/configure/wizard/CloneServerGroup.ecs.controller.js +259 -0
- package/src/serverGroup/configure/wizard/advancedSettings/advancedSettings.component.html +194 -0
- package/src/serverGroup/configure/wizard/advancedSettings/advancedSettings.component.js +17 -0
- package/src/serverGroup/configure/wizard/advancedSettings/advancedSettings.html +10 -0
- package/src/serverGroup/configure/wizard/capacityProvider/CapacityProvider.tsx +381 -0
- package/src/serverGroup/configure/wizard/capacityProvider/capacityProvider.html +11 -0
- package/src/serverGroup/configure/wizard/container/Container.tsx +347 -0
- package/src/serverGroup/configure/wizard/container/container.html +9 -0
- package/src/serverGroup/configure/wizard/horizontalScaling/horizontalScaling.component.html +118 -0
- package/src/serverGroup/configure/wizard/horizontalScaling/horizontalScaling.component.js +20 -0
- package/src/serverGroup/configure/wizard/horizontalScaling/horizontalScaling.html +13 -0
- package/src/serverGroup/configure/wizard/location/ServerGroupBasicSettings.controller.js +41 -0
- package/src/serverGroup/configure/wizard/location/basicSettings.html +137 -0
- package/src/serverGroup/configure/wizard/logging/logging.component.html +29 -0
- package/src/serverGroup/configure/wizard/logging/logging.component.ts +12 -0
- package/src/serverGroup/configure/wizard/logging/logging.html +7 -0
- package/src/serverGroup/configure/wizard/networking/Networking.tsx +261 -0
- package/src/serverGroup/configure/wizard/networking/networking.html +9 -0
- package/src/serverGroup/configure/wizard/serverGroupWizard.html +55 -0
- package/src/serverGroup/configure/wizard/serviceDiscovery/ServiceDiscovery.tsx +250 -0
- package/src/serverGroup/configure/wizard/serviceDiscovery/serviceDiscovery.html +11 -0
- package/src/serverGroup/configure/wizard/taskDefinition/TaskDefinition.tsx +460 -0
- package/src/serverGroup/configure/wizard/taskDefinition/taskDefinition.html +51 -0
- package/src/serverGroup/configure/wizard/templateSelection/templateSelection.html +9 -0
- package/src/serverGroup/configure/wizard/verticalScaling/verticalScaling.html +10 -0
- package/src/serverGroup/details/resize/resizeCapacity.component.html +94 -0
- package/src/serverGroup/details/resize/resizeCapacity.component.ts +14 -0
- package/src/serverGroup/details/resize/resizeServerGroup.controller.js +85 -0
- package/src/serverGroup/details/resize/resizeServerGroup.html +28 -0
- package/src/serverGroup/details/rollback/rollbackServerGroup.controller.js +97 -0
- package/src/serverGroup/details/rollback/rollbackServerGroup.html +67 -0
- package/src/serverGroup/details/serverGroupDetails.ecs.controller.js +366 -0
- package/src/serverGroup/details/serverGroupDetails.html +216 -0
- package/src/serverGroup/details/serverGroupDetails.module.ts +5 -0
- package/src/serverGroup/events/EventsLink.tsx +5 -0
- package/src/serverGroup/events/events.component.ts +35 -0
- package/src/serverGroup/events/events.controller.ts +45 -0
- package/src/serverGroup/events/events.html +36 -0
- package/src/serverGroup/events/serverGroupEventsReader.service.ts +27 -0
- package/src/serverGroup/serverGroup.module.ts +6 -0
- package/src/serverGroup/serverGroup.transformer.spec.ts +184 -0
- package/src/serverGroup/serverGroup.transformer.ts +117 -0
- package/src/serviceDiscovery/IServiceDiscovery.ts +13 -0
- package/src/serviceDiscovery/serviceDiscovery.read.service.ts +8 -0
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
import UIROUTER_ANGULARJS from '@uirouter/angularjs';
|
|
4
|
+
import { module } from 'angular';
|
|
5
|
+
import ANGULAR_UI_BOOTSTRAP from 'angular-ui-bootstrap';
|
|
6
|
+
import _ from 'lodash';
|
|
7
|
+
|
|
8
|
+
import { applyHealthCheckInfoToTargetGroups, getAllTargetGroups } from '@spinnaker/amazon';
|
|
9
|
+
import {
|
|
10
|
+
CloudProviderRegistry,
|
|
11
|
+
ConfirmationModalService,
|
|
12
|
+
InstanceReader,
|
|
13
|
+
InstanceWriter,
|
|
14
|
+
RecentHistoryService,
|
|
15
|
+
SETTINGS,
|
|
16
|
+
} from '@spinnaker/core';
|
|
17
|
+
|
|
18
|
+
export const ECS_INSTANCE_DETAILS_INSTANCE_DETAILS_CONTROLLER = 'spinnaker.ecs.instance.details.controller';
|
|
19
|
+
export const name = ECS_INSTANCE_DETAILS_INSTANCE_DETAILS_CONTROLLER; // for backwards compatibility
|
|
20
|
+
module(ECS_INSTANCE_DETAILS_INSTANCE_DETAILS_CONTROLLER, [UIROUTER_ANGULARJS, ANGULAR_UI_BOOTSTRAP]).controller(
|
|
21
|
+
'ecsInstanceDetailsCtrl',
|
|
22
|
+
[
|
|
23
|
+
'$scope',
|
|
24
|
+
'$state',
|
|
25
|
+
'$uibModal',
|
|
26
|
+
'instance',
|
|
27
|
+
'app',
|
|
28
|
+
'moniker',
|
|
29
|
+
'environment',
|
|
30
|
+
'$q',
|
|
31
|
+
'overrides',
|
|
32
|
+
function ($scope, $state, $uibModal, instance, app, moniker, environment, $q, overrides) {
|
|
33
|
+
// needed for standalone instances
|
|
34
|
+
$scope.detailsTemplateUrl = CloudProviderRegistry.getValue('ecs', 'instance.detailsTemplateUrl');
|
|
35
|
+
|
|
36
|
+
$scope.state = {
|
|
37
|
+
loading: true,
|
|
38
|
+
standalone: app.isStandalone,
|
|
39
|
+
instancePort: _.get(app, 'attributes.instancePort') || SETTINGS.defaultInstancePort || 80,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
$scope.application = app;
|
|
43
|
+
$scope.moniker = moniker;
|
|
44
|
+
$scope.environment = environment;
|
|
45
|
+
|
|
46
|
+
const cloudProvider = 'ecs';
|
|
47
|
+
const defaultRequestParams = { cloudProvider: cloudProvider };
|
|
48
|
+
|
|
49
|
+
function extractHealthMetrics(instance, latest) {
|
|
50
|
+
// do not backfill on standalone instances
|
|
51
|
+
if (app.isStandalone) {
|
|
52
|
+
instance.health = latest.health;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
instance.health = instance.health || [];
|
|
56
|
+
const displayableMetrics = instance.health.filter(function (metric) {
|
|
57
|
+
return metric.type !== 'Ecs' || metric.state !== 'Unknown';
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// augment with target group healthcheck data
|
|
61
|
+
const targetGroups = getAllTargetGroups(app.loadBalancers.data);
|
|
62
|
+
applyHealthCheckInfoToTargetGroups(displayableMetrics, targetGroups, instance.account);
|
|
63
|
+
|
|
64
|
+
// backfill details where applicable
|
|
65
|
+
if (latest.health) {
|
|
66
|
+
displayableMetrics.forEach(function (metric) {
|
|
67
|
+
const detailsMatch = latest.health.filter(function (latestHealth) {
|
|
68
|
+
return latestHealth.type === metric.type;
|
|
69
|
+
});
|
|
70
|
+
if (detailsMatch.length) {
|
|
71
|
+
_.defaults(metric, detailsMatch[0]);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
$scope.healthMetrics = displayableMetrics;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function retrieveInstance() {
|
|
79
|
+
const extraData = {};
|
|
80
|
+
let instanceSummary, loadBalancers, targetGroup, account, region, vpcId;
|
|
81
|
+
if (!app.serverGroups) {
|
|
82
|
+
// standalone instance
|
|
83
|
+
instanceSummary = {};
|
|
84
|
+
loadBalancers = [];
|
|
85
|
+
targetGroup = [];
|
|
86
|
+
account = instance.account;
|
|
87
|
+
region = instance.region;
|
|
88
|
+
} else {
|
|
89
|
+
app.serverGroups.data.some(function (serverGroup) {
|
|
90
|
+
return serverGroup.instances.some(function (possibleInstance) {
|
|
91
|
+
if (possibleInstance.id === instance.instanceId) {
|
|
92
|
+
instanceSummary = possibleInstance;
|
|
93
|
+
loadBalancers = serverGroup.loadBalancers;
|
|
94
|
+
targetGroup = serverGroup.targetGroup;
|
|
95
|
+
account = serverGroup.account;
|
|
96
|
+
region = serverGroup.region;
|
|
97
|
+
vpcId = serverGroup.vpcId;
|
|
98
|
+
extraData.serverGroup = serverGroup.name;
|
|
99
|
+
extraData.vpcId = serverGroup.vpcId;
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
if (!instanceSummary) {
|
|
105
|
+
// perhaps it is in a server group that is part of another app
|
|
106
|
+
app.loadBalancers.data.some(function (loadBalancer) {
|
|
107
|
+
return (
|
|
108
|
+
loadBalancer.instances.some(function (possibleInstance) {
|
|
109
|
+
if (possibleInstance.id === instance.instanceId) {
|
|
110
|
+
instanceSummary = possibleInstance;
|
|
111
|
+
loadBalancers = [loadBalancer.name];
|
|
112
|
+
account = loadBalancer.account;
|
|
113
|
+
region = loadBalancer.region;
|
|
114
|
+
vpcId = loadBalancer.vpcId;
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
}) ||
|
|
118
|
+
loadBalancer.targetGroup.some(function (targetGroup) {
|
|
119
|
+
return targetGroup.instances.some(function (possibleInstance) {
|
|
120
|
+
if (possibleInstance.id === instance.instanceId) {
|
|
121
|
+
instanceSummary = possibleInstance;
|
|
122
|
+
targetGroup = targetGroup.name;
|
|
123
|
+
account = loadBalancer.account;
|
|
124
|
+
region = loadBalancer.region;
|
|
125
|
+
vpcId = loadBalancer.vpcId;
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
})
|
|
130
|
+
);
|
|
131
|
+
});
|
|
132
|
+
if (!instanceSummary) {
|
|
133
|
+
// perhaps it is in a disabled server group via a load balancer
|
|
134
|
+
app.loadBalancers.data.some(function (loadBalancer) {
|
|
135
|
+
return (
|
|
136
|
+
loadBalancer.serverGroups.some(function (serverGroup) {
|
|
137
|
+
if (!serverGroup.isDisabled) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
return serverGroup.instances.some(function (possibleInstance) {
|
|
141
|
+
if (possibleInstance.id === instance.instanceId) {
|
|
142
|
+
instanceSummary = possibleInstance;
|
|
143
|
+
loadBalancers = [loadBalancer.name];
|
|
144
|
+
account = loadBalancer.account;
|
|
145
|
+
region = loadBalancer.region;
|
|
146
|
+
vpcId = loadBalancer.vpcId;
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}) ||
|
|
151
|
+
loadBalancer.targetGroup.some(function (targetGroup) {
|
|
152
|
+
targetGroup.serverGroups.some(function (serverGroup) {
|
|
153
|
+
if (!serverGroup.isDisabled) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
return serverGroup.instances.some(function (possibleInstance) {
|
|
157
|
+
if (possibleInstance.id === instance.instanceId) {
|
|
158
|
+
instanceSummary = possibleInstance;
|
|
159
|
+
loadBalancers = [loadBalancer.name];
|
|
160
|
+
account = loadBalancer.account;
|
|
161
|
+
region = loadBalancer.region;
|
|
162
|
+
vpcId = loadBalancer.vpcId;
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
})
|
|
168
|
+
);
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (instanceSummary && account && region) {
|
|
175
|
+
instanceSummary.account = account;
|
|
176
|
+
extraData.account = account;
|
|
177
|
+
extraData.region = region;
|
|
178
|
+
RecentHistoryService.addExtraDataToLatest('instances', extraData);
|
|
179
|
+
return InstanceReader.getInstanceDetails(account, region, instance.instanceId).then((details) => {
|
|
180
|
+
if ($scope.$$destroyed) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
$scope.state.loading = false;
|
|
184
|
+
extractHealthMetrics(instanceSummary, details);
|
|
185
|
+
$scope.instance = _.defaults(details, instanceSummary);
|
|
186
|
+
$scope.instance.account = account;
|
|
187
|
+
$scope.instance.region = region;
|
|
188
|
+
$scope.instance.vpcId = vpcId;
|
|
189
|
+
$scope.instance.loadBalancers = loadBalancers;
|
|
190
|
+
$scope.instance.targetGroup = targetGroup;
|
|
191
|
+
if ($scope.instance.networkInterfaces) {
|
|
192
|
+
const permanentNetworkInterfaces = $scope.instance.networkInterfaces.filter(
|
|
193
|
+
(f) => f.attachment.deleteOnTermination === false,
|
|
194
|
+
);
|
|
195
|
+
if (permanentNetworkInterfaces.length) {
|
|
196
|
+
$scope.instance.permanentIps = permanentNetworkInterfaces.map((f) => f.privateIpAddress);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
$scope.baseIpAddress = details.publicDnsName || details.privateIpAddress;
|
|
200
|
+
if (overrides.instanceDetailsLoaded) {
|
|
201
|
+
overrides.instanceDetailsLoaded();
|
|
202
|
+
}
|
|
203
|
+
}, autoClose);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (!instanceSummary) {
|
|
207
|
+
$scope.instanceIdNotFound = instance.instanceId;
|
|
208
|
+
$scope.state.loading = false;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return $q.when(null);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function autoClose() {
|
|
215
|
+
if ($scope.$$destroyed) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
if (app.isStandalone) {
|
|
219
|
+
$scope.state.loading = false;
|
|
220
|
+
$scope.instanceIdNotFound = instance.instanceId;
|
|
221
|
+
$scope.state.notFoundStandalone = true;
|
|
222
|
+
RecentHistoryService.removeLastItem('instances');
|
|
223
|
+
} else {
|
|
224
|
+
$state.go('^', { allowModalToStayOpen: true }, { location: 'replace' });
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
this.canRegisterWithDiscovery = function () {
|
|
229
|
+
const instance = $scope.instance;
|
|
230
|
+
const healthMetrics = instance.health || [];
|
|
231
|
+
const discoveryHealth = healthMetrics.filter(function (health) {
|
|
232
|
+
return health.type === 'Discovery';
|
|
233
|
+
});
|
|
234
|
+
return discoveryHealth.length ? discoveryHealth[0].state === 'OutOfService' : false;
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
this.terminateInstance = function terminateInstance() {
|
|
238
|
+
const instance = $scope.instance;
|
|
239
|
+
|
|
240
|
+
const taskMonitor = {
|
|
241
|
+
application: app,
|
|
242
|
+
title: 'Terminating ' + instance.instanceId,
|
|
243
|
+
onTaskComplete: function () {
|
|
244
|
+
if ($state.includes('**.instanceDetails', { instanceId: instance.instanceId })) {
|
|
245
|
+
$state.go('^');
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const submitMethod = function () {
|
|
251
|
+
return InstanceWriter.terminateInstance(instance, app, defaultRequestParams);
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
ConfirmationModalService.confirm({
|
|
255
|
+
header: 'Really terminate ' + instance.instanceId + '?',
|
|
256
|
+
buttonText: 'Terminate ' + instance.instanceId,
|
|
257
|
+
account: instance.account,
|
|
258
|
+
taskMonitorConfig: taskMonitor,
|
|
259
|
+
submitMethod: submitMethod,
|
|
260
|
+
});
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
this.terminateInstanceAndShrinkServerGroup = function terminateInstanceAndShrinkServerGroup() {
|
|
264
|
+
const instance = $scope.instance;
|
|
265
|
+
|
|
266
|
+
const taskMonitor = {
|
|
267
|
+
application: app,
|
|
268
|
+
title: 'Terminating ' + instance.instanceId + ' and shrinking server group',
|
|
269
|
+
onTaskComplete: function () {
|
|
270
|
+
if ($state.includes('**.instanceDetails', { instanceId: instance.instanceId })) {
|
|
271
|
+
$state.go('^');
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
const submitMethod = function () {
|
|
277
|
+
return InstanceWriter.terminateInstanceAndShrinkServerGroup(instance, app, defaultRequestParams);
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
ConfirmationModalService.confirm({
|
|
281
|
+
header: 'Really terminate ' + instance.instanceId + ' and shrink ' + instance.serverGroup + '?',
|
|
282
|
+
buttonText: 'Terminate ' + instance.instanceId + ' and shrink ' + instance.serverGroup,
|
|
283
|
+
account: instance.account,
|
|
284
|
+
taskMonitorConfig: taskMonitor,
|
|
285
|
+
submitMethod: submitMethod,
|
|
286
|
+
});
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
this.enableInstanceInDiscovery = function enableInstanceInDiscovery() {
|
|
290
|
+
const instance = $scope.instance;
|
|
291
|
+
|
|
292
|
+
const taskMonitor = {
|
|
293
|
+
application: app,
|
|
294
|
+
title: 'Enabling ' + instance.instanceId + ' in discovery',
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
const submitMethod = function () {
|
|
298
|
+
return InstanceWriter.enableInstanceInDiscovery(instance, app, defaultRequestParams);
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
ConfirmationModalService.confirm({
|
|
302
|
+
header: 'Really enable ' + instance.instanceId + ' in discovery?',
|
|
303
|
+
buttonText: 'Enable ' + instance.instanceId,
|
|
304
|
+
account: instance.account,
|
|
305
|
+
taskMonitorConfig: taskMonitor,
|
|
306
|
+
submitMethod: submitMethod,
|
|
307
|
+
});
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
this.disableInstanceInDiscovery = function disableInstanceInDiscovery() {
|
|
311
|
+
const instance = $scope.instance;
|
|
312
|
+
|
|
313
|
+
const taskMonitor = {
|
|
314
|
+
application: app,
|
|
315
|
+
title: 'Disabling ' + instance.instanceId + ' in discovery',
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
const submitMethod = function () {
|
|
319
|
+
return InstanceWriter.disableInstanceInDiscovery(instance, app, defaultRequestParams);
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
ConfirmationModalService.confirm({
|
|
323
|
+
header: 'Really disable ' + instance.instanceId + ' in discovery?',
|
|
324
|
+
buttonText: 'Disable ' + instance.instanceId,
|
|
325
|
+
account: instance.account,
|
|
326
|
+
taskMonitorConfig: taskMonitor,
|
|
327
|
+
submitMethod: submitMethod,
|
|
328
|
+
});
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
this.hasHealthState = function hasHealthState(healthProviderType, state) {
|
|
332
|
+
const instance = $scope.instance;
|
|
333
|
+
const healthMetrics = instance.health || [];
|
|
334
|
+
return healthMetrics.some(function (health) {
|
|
335
|
+
return health.type === healthProviderType && health.state === state;
|
|
336
|
+
});
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
const initialize = app.isStandalone
|
|
340
|
+
? retrieveInstance()
|
|
341
|
+
: $q.all([app.serverGroups.ready(), app.loadBalancers.ready()]).then(retrieveInstance);
|
|
342
|
+
|
|
343
|
+
initialize.then(() => {
|
|
344
|
+
// Two things to look out for here:
|
|
345
|
+
// 1. If the retrieveInstance call completes *after* the user has navigated away from the view, there
|
|
346
|
+
// is no point in subscribing to the refresh
|
|
347
|
+
// 2. If this is a standalone instance, there is no application that will refresh
|
|
348
|
+
if (!$scope.$$destroyed && !app.isStandalone) {
|
|
349
|
+
app.serverGroups.onRefresh($scope, retrieveInstance);
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
$scope.account = instance.account;
|
|
354
|
+
},
|
|
355
|
+
],
|
|
356
|
+
);
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
<div class="text-center" ng-if="state.notFoundStandalone">
|
|
2
|
+
<h3>Could not find instance {{instanceIdNotFound}}.</h3>
|
|
3
|
+
<a ui-sref="home.infrastructure">Back to search results</a>
|
|
4
|
+
</div>
|
|
5
|
+
<div class="details-panel" ng-if="!state.notFoundStandalone">
|
|
6
|
+
<div class="header">
|
|
7
|
+
<instance-details-header
|
|
8
|
+
health-state="instance.healthState"
|
|
9
|
+
instance-id="instance ? instance.name : instanceIdNotFound"
|
|
10
|
+
loading="state.loading"
|
|
11
|
+
standalone="state.standalone"
|
|
12
|
+
></instance-details-header>
|
|
13
|
+
<div ng-if="!state.loading">
|
|
14
|
+
<div class="actions" ng-class="{ insights: instance.insightActions.length > 0 }">
|
|
15
|
+
<!-- TODO - find out what I should do with ng-if="instance.placement" -->
|
|
16
|
+
<div class="dropdown" uib-dropdown dropdown-append-to-body>
|
|
17
|
+
<button
|
|
18
|
+
type="button"
|
|
19
|
+
class="btn btn-sm btn-primary dropdown-toggle"
|
|
20
|
+
ng-disabled="disabled"
|
|
21
|
+
uib-dropdown-toggle
|
|
22
|
+
>
|
|
23
|
+
Instance Actions <span class="caret"></span>
|
|
24
|
+
</button>
|
|
25
|
+
<ul class="dropdown-menu" uib-dropdown-menu role="menu">
|
|
26
|
+
<li>
|
|
27
|
+
<a href ng-click="ctrl.enableInstanceInDiscovery()" ng-if="ctrl.canRegisterWithDiscovery()"
|
|
28
|
+
>Enable in Discovery</a
|
|
29
|
+
>
|
|
30
|
+
</li>
|
|
31
|
+
<li>
|
|
32
|
+
<a
|
|
33
|
+
href
|
|
34
|
+
ng-click="ctrl.disableInstanceInDiscovery()"
|
|
35
|
+
ng-if="ctrl.hasHealthState('Discovery', 'Up') || ctrl.hasHealthState('Discovery', 'Down')"
|
|
36
|
+
>Disable in Discovery</a
|
|
37
|
+
>
|
|
38
|
+
</li>
|
|
39
|
+
<li>
|
|
40
|
+
<a href ng-click="ctrl.registerInstanceWithLoadBalancer()" ng-if="ctrl.canRegisterWithLoadBalancer()"
|
|
41
|
+
>Register with Load Balancer</a
|
|
42
|
+
>
|
|
43
|
+
</li>
|
|
44
|
+
<li>
|
|
45
|
+
<a href ng-click="ctrl.deregisterInstanceFromLoadBalancer()" ng-if="ctrl.canDeregisterFromLoadBalancer()"
|
|
46
|
+
>Deregister from Load Balancer</a
|
|
47
|
+
>
|
|
48
|
+
</li>
|
|
49
|
+
<li>
|
|
50
|
+
<a href ng-click="ctrl.registerInstanceWithTargetGroup()" ng-if="ctrl.canRegisterWithTargetGroup()"
|
|
51
|
+
>Register with Target Group</a
|
|
52
|
+
>
|
|
53
|
+
</li>
|
|
54
|
+
<li>
|
|
55
|
+
<a href ng-click="ctrl.deregisterInstanceFromTargetGroup()" ng-if="ctrl.canDeregisterFromTargetGroup()"
|
|
56
|
+
>Deregister from Target Group</a
|
|
57
|
+
>
|
|
58
|
+
</li>
|
|
59
|
+
<!--<li role="presentation" class="divider" ng-if="instance.health.length > 0"></li>-->
|
|
60
|
+
</ul>
|
|
61
|
+
</div>
|
|
62
|
+
<div class="dropdown" ng-if="instance.insightActions.length > 0" uib-dropdown dropdown-append-to-body>
|
|
63
|
+
<button type="button" class="btn btn-sm btn-default dropdown-toggle" uib-dropdown-toggle>
|
|
64
|
+
Insight <span class="caret"></span>
|
|
65
|
+
</button>
|
|
66
|
+
<ul class="dropdown-menu" uib-dropdown-menu role="menu">
|
|
67
|
+
<li ng-repeat="action in instance.insightActions">
|
|
68
|
+
<a target="_blank" href="{{action.url}}">{{action.label}}</a>
|
|
69
|
+
</li>
|
|
70
|
+
</ul>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
<div class="content" data-test-id="instanceDetails.content" ng-if="!state.loading && instance">
|
|
76
|
+
<collapsible-section heading="Instance Information" expanded="true">
|
|
77
|
+
<dl class="dl-horizontal dl-narrow">
|
|
78
|
+
<dt>Launched</dt>
|
|
79
|
+
<dd ng-if="instance.launchTime">{{instance.launchTime | timestamp}}</dd>
|
|
80
|
+
<dd ng-if="!instance.launchTime">(Unknown)</dd>
|
|
81
|
+
<dt ng-if="instance.serverGroup">Server Group</dt>
|
|
82
|
+
<dd ng-if="instance.serverGroup">
|
|
83
|
+
<a
|
|
84
|
+
ui-sref="^.serverGroup({region: instance.region,
|
|
85
|
+
accountId: instance.account,
|
|
86
|
+
serverGroup: instance.serverGroup,
|
|
87
|
+
provider: instance.provider})"
|
|
88
|
+
>{{instance.serverGroup}}</a
|
|
89
|
+
>
|
|
90
|
+
</dd>
|
|
91
|
+
<dt ng-if="instance.imageId">Image ID</dt>
|
|
92
|
+
<dd ng-if="instance.imageId">{{instance.imageId}}</dd>
|
|
93
|
+
</dl>
|
|
94
|
+
</collapsible-section>
|
|
95
|
+
<collapsible-section heading="Status" expanded="true">
|
|
96
|
+
<p ng-if="instance.healthState !== 'Starting' && !healthMetrics.length">
|
|
97
|
+
No health metrics found for this instance
|
|
98
|
+
</p>
|
|
99
|
+
<p ng-if="instance.healthState === 'Starting' && !healthMetrics.length">
|
|
100
|
+
<span class="glyphicon glyphicon-Starting-triangle"></span> <strong>Starting</strong>
|
|
101
|
+
</p>
|
|
102
|
+
|
|
103
|
+
<dl class="horizontal-when-filters-collapsed">
|
|
104
|
+
<dt ng-repeat-start="metric in healthMetrics | orderBy: 'type'">{{metric.type | robotToHuman}}</dt>
|
|
105
|
+
<dd ng-repeat-end>
|
|
106
|
+
<div ng-if="metric.type !== 'LoadBalancer' && metric.type !== 'TargetGroup'">
|
|
107
|
+
<span
|
|
108
|
+
uib-tooltip="{{metric.state.toLowerCase() === 'down' ? metric.description : ''}}"
|
|
109
|
+
tooltip-placement="left"
|
|
110
|
+
>
|
|
111
|
+
<span class="glyphicon glyphicon-{{metric.state}}-triangle"></span>
|
|
112
|
+
{{metric.state | robotToHuman}}
|
|
113
|
+
</span>
|
|
114
|
+
<span class="pad-left small">
|
|
115
|
+
<a ng-if="metric.healthCheckUrl" target="_blank" href="{{metric.healthCheckUrl}}">Health Check</a>
|
|
116
|
+
<span ng-if="metric.healthCheckUrl && metric.statusPageUrl"> | </span>
|
|
117
|
+
<a ng-if="metric.statusPageUrl" target="_blank" href="{{metric.statusPageUrl}}">Status</a>
|
|
118
|
+
</span>
|
|
119
|
+
</div>
|
|
120
|
+
<div
|
|
121
|
+
ng-if="metric.type === 'LoadBalancer' && metric.loadBalancers.length"
|
|
122
|
+
ng-repeat="loadBalancer in metric.loadBalancers"
|
|
123
|
+
>
|
|
124
|
+
<instance-load-balancer-health load-balancer="loadBalancer"></instance-load-balancer-health>
|
|
125
|
+
</div>
|
|
126
|
+
<div
|
|
127
|
+
ng-if="metric.type === 'TargetGroup' && metric.targetGroups.length"
|
|
128
|
+
ng-repeat="targetGroup in metric.targetGroups"
|
|
129
|
+
>
|
|
130
|
+
<instance-load-balancer-health
|
|
131
|
+
load-balancer="targetGroup"
|
|
132
|
+
ip-address="baseIpAddress"
|
|
133
|
+
></instance-load-balancer-health>
|
|
134
|
+
</div>
|
|
135
|
+
</dd>
|
|
136
|
+
</dl>
|
|
137
|
+
</collapsible-section>
|
|
138
|
+
<collapsible-section heading="Networking">
|
|
139
|
+
<dl class="horizontal-when-filters-collapsed">
|
|
140
|
+
<dt ng-if="instance.vpcId">VPC</dt>
|
|
141
|
+
<dd ng-if="instance.vpcId"><vpc-tag vpc-id="instance.vpcId"></vpc-tag></dd>
|
|
142
|
+
<dt ng-if="instance.subnetId">Subnet</dt>
|
|
143
|
+
<dd ng-if="instance.subnetId"><subnet-tag subnet-id="instance.subnetId"></subnet-tag></dd>
|
|
144
|
+
|
|
145
|
+
<dt ng-if="instance.privateAddress || instance.networkInterface">IP</dt>
|
|
146
|
+
<dd ng-if="instance.networkInterface.privateIpv4Address">
|
|
147
|
+
Private address (ENI):
|
|
148
|
+
<a href="http://{{instance.networkInterface.privateIpv4Address}}" target="_blank"
|
|
149
|
+
>{{instance.networkInterface.privateIpv4Address}}</a
|
|
150
|
+
>
|
|
151
|
+
<copy-to-clipboard
|
|
152
|
+
class="copy-to-clipboard copy-to-clipboard-sm"
|
|
153
|
+
text="instance.networkInterface.privateIpv4Address"
|
|
154
|
+
tool-tip="'Copy to clipboard'"
|
|
155
|
+
>
|
|
156
|
+
</copy-to-clipboard>
|
|
157
|
+
</dd>
|
|
158
|
+
<dd ng-if="instance.networkInterface.ipv6Address">
|
|
159
|
+
Private address (ENI):
|
|
160
|
+
<a href="http://{{instance.networkInterface.ipv6Address}}" target="_blank"
|
|
161
|
+
>{{instance.networkInterface.ipv6Address}}</a
|
|
162
|
+
>
|
|
163
|
+
<copy-to-clipboard
|
|
164
|
+
class="copy-to-clipboard copy-to-clipboard-sm"
|
|
165
|
+
text="instance.networkInterface.ipv6Address"
|
|
166
|
+
tool-tip="'Copy to clipboard'"
|
|
167
|
+
>
|
|
168
|
+
</copy-to-clipboard>
|
|
169
|
+
</dd>
|
|
170
|
+
<dd ng-if="instance.privateAddress">
|
|
171
|
+
Private address (Bridge):
|
|
172
|
+
<a href="http://{{instance.privateAddress}}" target="_blank">{{instance.privateAddress}}</a>
|
|
173
|
+
<copy-to-clipboard
|
|
174
|
+
class="copy-to-clipboard copy-to-clipboard-sm"
|
|
175
|
+
text="instance.privateAddress"
|
|
176
|
+
tool-tip="'Copy to clipboard'"
|
|
177
|
+
>
|
|
178
|
+
</copy-to-clipboard>
|
|
179
|
+
</dd>
|
|
180
|
+
</dl>
|
|
181
|
+
</collapsible-section>
|
|
182
|
+
<collapsible-section heading="Console Output" ng-if="baseIpAddress">
|
|
183
|
+
<ul>
|
|
184
|
+
<li>
|
|
185
|
+
<console-output-link instance="instance"></console-output-link>
|
|
186
|
+
</li>
|
|
187
|
+
</ul>
|
|
188
|
+
</collapsible-section>
|
|
189
|
+
<instance-links
|
|
190
|
+
address="baseIpAddress"
|
|
191
|
+
application="application"
|
|
192
|
+
instance="instance"
|
|
193
|
+
moniker="moniker"
|
|
194
|
+
environment="environment"
|
|
195
|
+
></instance-links>
|
|
196
|
+
</div>
|
|
197
|
+
<div class="content" ng-if="!state.loading && !instance">
|
|
198
|
+
<div class="content-section">
|
|
199
|
+
<div class="content-body text-center">
|
|
200
|
+
<h3>Instance not found.</h3>
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
204
|
+
</div>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { isEqual } from 'lodash';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
import type { ILoadBalancerClusterContainerProps } from '@spinnaker/core';
|
|
5
|
+
|
|
6
|
+
import { EcsTargetGroup } from './TargetGroup';
|
|
7
|
+
import type { IEcsLoadBalancer } from '../domain/IEcsLoadBalancer';
|
|
8
|
+
|
|
9
|
+
export class EcsLoadBalancerClusterContainer extends React.Component<ILoadBalancerClusterContainerProps> {
|
|
10
|
+
public shouldComponentUpdate(nextProps: ILoadBalancerClusterContainerProps) {
|
|
11
|
+
const serverGroupsDiffer = () =>
|
|
12
|
+
!isEqual(
|
|
13
|
+
(nextProps.serverGroups || []).map((g) => g.name),
|
|
14
|
+
(this.props.serverGroups || []).map((g) => g.name),
|
|
15
|
+
);
|
|
16
|
+
const targetGroupsDiffer = () =>
|
|
17
|
+
!isEqual(
|
|
18
|
+
((nextProps.loadBalancer as IEcsLoadBalancer).targetGroups || []).map((t) => t.targetGroupName),
|
|
19
|
+
((this.props.loadBalancer as IEcsLoadBalancer).targetGroups || []).map((t) => t.targetGroupName),
|
|
20
|
+
);
|
|
21
|
+
return (
|
|
22
|
+
nextProps.showInstances !== this.props.showInstances ||
|
|
23
|
+
nextProps.showServerGroups !== this.props.showServerGroups ||
|
|
24
|
+
nextProps.loadBalancer !== this.props.loadBalancer ||
|
|
25
|
+
serverGroupsDiffer() ||
|
|
26
|
+
targetGroupsDiffer()
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public render(): React.ReactElement<EcsLoadBalancerClusterContainer> {
|
|
31
|
+
const { loadBalancer, showInstances, showServerGroups } = this.props;
|
|
32
|
+
const lb = loadBalancer as IEcsLoadBalancer;
|
|
33
|
+
|
|
34
|
+
const TargetGroups = lb.targetGroups.map((targetGroup) => {
|
|
35
|
+
return (
|
|
36
|
+
<EcsTargetGroup
|
|
37
|
+
key={targetGroup.targetGroupName}
|
|
38
|
+
loadBalancer={loadBalancer as IEcsLoadBalancer}
|
|
39
|
+
targetGroup={targetGroup}
|
|
40
|
+
showInstances={showInstances}
|
|
41
|
+
showServerGroups={showServerGroups}
|
|
42
|
+
/>
|
|
43
|
+
);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
return <div className="cluster-container">{TargetGroups}</div>;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { UISref, UISrefActive } from '@uirouter/react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
import type { IInstanceCounts } from '@spinnaker/core';
|
|
5
|
+
import { LoadBalancerServerGroup } from '@spinnaker/core';
|
|
6
|
+
|
|
7
|
+
import type { IEcsLoadBalancer, IEcsTargetGroup } from '../domain/IEcsLoadBalancer';
|
|
8
|
+
|
|
9
|
+
export interface IEcsTargetGroupProps {
|
|
10
|
+
loadBalancer: IEcsLoadBalancer;
|
|
11
|
+
targetGroup: IEcsTargetGroup;
|
|
12
|
+
showServerGroups: boolean;
|
|
13
|
+
showInstances: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export class EcsTargetGroup extends React.Component<IEcsTargetGroupProps> {
|
|
17
|
+
public render(): React.ReactElement<EcsTargetGroup> {
|
|
18
|
+
const { targetGroup, loadBalancer, showServerGroups } = this.props;
|
|
19
|
+
|
|
20
|
+
const params = {
|
|
21
|
+
loadBalancerName: loadBalancer.name,
|
|
22
|
+
region: targetGroup.region,
|
|
23
|
+
accountId: targetGroup.account,
|
|
24
|
+
name: targetGroup.targetGroupName,
|
|
25
|
+
vpcId: targetGroup.vpcId,
|
|
26
|
+
provider: targetGroup.cloudProvider,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// info not yet available; HealthCounts component requires it,
|
|
30
|
+
// but will not render if no values are defined.
|
|
31
|
+
const emptyInstanceCounts: IInstanceCounts = {
|
|
32
|
+
up: undefined,
|
|
33
|
+
down: undefined,
|
|
34
|
+
starting: undefined,
|
|
35
|
+
succeeded: undefined,
|
|
36
|
+
failed: undefined,
|
|
37
|
+
unknown: undefined,
|
|
38
|
+
outOfService: undefined,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<div className="target-group-container container-fluid no-padding">
|
|
43
|
+
<UISrefActive class="active">
|
|
44
|
+
<UISref to=".ecsTargetGroupDetails" params={params}>
|
|
45
|
+
<div className={`clickable clickable-row row no-margin-y target-group-header`}>
|
|
46
|
+
<div className="col-md-8 target-group-title">{targetGroup.targetGroupName}</div>
|
|
47
|
+
</div>
|
|
48
|
+
</UISref>
|
|
49
|
+
</UISrefActive>
|
|
50
|
+
{showServerGroups &&
|
|
51
|
+
targetGroup.serverGroups.map((sgName) => {
|
|
52
|
+
return (
|
|
53
|
+
<LoadBalancerServerGroup
|
|
54
|
+
key={sgName}
|
|
55
|
+
account={targetGroup.account}
|
|
56
|
+
region={targetGroup.region}
|
|
57
|
+
serverGroup={{
|
|
58
|
+
account: targetGroup.account,
|
|
59
|
+
cloudProvider: targetGroup.cloudProvider,
|
|
60
|
+
cluster: sgName,
|
|
61
|
+
instanceCounts: emptyInstanceCounts,
|
|
62
|
+
instances: targetGroup.instances,
|
|
63
|
+
name: sgName,
|
|
64
|
+
type: targetGroup.type,
|
|
65
|
+
region: targetGroup.region,
|
|
66
|
+
}}
|
|
67
|
+
showInstances={false} // TODO: use prop when instanceCounts available
|
|
68
|
+
/>
|
|
69
|
+
);
|
|
70
|
+
})}
|
|
71
|
+
</div>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
}
|