@spinnaker/azure 2026.2.2 → 2026.3.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.
- package/dist/azure.module.d.ts +3 -1
- package/dist/image/image.reader.d.ts +4 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/instance/azureInstanceType.service.d.ts +6 -2
- package/dist/instance/details/AzureInstanceDetails.d.ts +67 -0
- package/dist/loadBalancer/configure/AzureLoadBalancerChoiceModal.d.ts +10 -5
- package/dist/loadBalancer/configure/AzureLoadBalancerModal.d.ts +102 -0
- package/dist/loadBalancer/details/azureLoadBalancerDetails.d.ts +26 -0
- package/dist/loadBalancer/loadBalancer.transformer.d.ts +45 -2
- package/dist/pipeline/stages/AzureAccountRegionClusterSelector.d.ts +32 -0
- package/dist/pipeline/stages/bake/azureBakeStage.d.ts +46 -2
- package/dist/pipeline/stages/destroyAsg/azureDestroyAsgStage.d.ts +14 -2
- package/dist/pipeline/stages/disableAsg/azureDisableAsgStage.d.ts +4 -2
- package/dist/pipeline/stages/enableAsg/azureEnableAsgStage.d.ts +4 -2
- package/dist/securityGroup/configure/AzureSecurityGroupModal.d.ts +70 -0
- package/dist/securityGroup/details/AzureSecurityGroupDetails.d.ts +51 -0
- package/dist/securityGroup/securityGroup.reader.d.ts +3 -2
- package/dist/securityGroup/securityGroup.transformer.d.ts +3 -2
- package/dist/securityGroup/securityGroup.write.service.d.ts +9 -2
- package/dist/serverGroup/configure/serverGroupCommandBuilder.service.d.ts +88 -2
- package/dist/serverGroup/configure/serverGroupConfiguration.service.d.ts +30 -2
- package/dist/serverGroup/configure/wizard/AzureCloneServerGroupModal.d.ts +44 -0
- package/dist/serverGroup/configure/wizard/pages/ServerGroupAdvancedSettings.d.ts +8 -0
- package/dist/serverGroup/configure/wizard/pages/ServerGroupBasicSettings.d.ts +12 -0
- package/dist/serverGroup/configure/wizard/pages/ServerGroupCapacityAndZones.d.ts +11 -0
- package/dist/serverGroup/configure/wizard/pages/ServerGroupHealthSettings.d.ts +10 -0
- package/dist/serverGroup/configure/wizard/pages/ServerGroupImageSettings.d.ts +12 -0
- package/dist/serverGroup/configure/wizard/pages/ServerGroupInstanceType.d.ts +9 -0
- package/dist/serverGroup/configure/wizard/pages/ServerGroupLoadBalancers.d.ts +14 -0
- package/dist/serverGroup/configure/wizard/pages/ServerGroupNetworkSettings.d.ts +10 -0
- package/dist/serverGroup/configure/wizard/pages/ServerGroupSecurityGroups.d.ts +6 -0
- package/dist/serverGroup/configure/wizard/pages/ServerGroupTags.d.ts +9 -0
- package/dist/serverGroup/configure/wizard/pages/common.d.ts +14 -0
- package/dist/serverGroup/configure/wizard/pages/index.d.ts +10 -0
- package/dist/serverGroup/details/azureServerGroupDetails.d.ts +13 -0
- package/dist/serverGroup/details/rollback/RollbackServerGroupModal.d.ts +6 -4
- package/dist/serverGroup/serverGroup.transformer.d.ts +61 -2
- package/dist/validation/applicationName.validator.d.ts +6 -2
- package/package.json +5 -8
- package/src/azure.module.spec.ts +921 -0
- package/src/azure.module.ts +56 -68
- package/src/image/image.reader.js +4 -15
- package/src/image/image.reader.spec.js +4 -7
- package/src/instance/azureInstanceType.service.js +8 -16
- package/src/instance/azureInstanceType.service.spec.js +5 -13
- package/src/instance/details/AzureInstanceDetails.spec.tsx +364 -0
- package/src/instance/details/AzureInstanceDetails.tsx +533 -0
- package/src/loadBalancer/configure/AzureLoadBalancerChoiceModal.spec.tsx +125 -0
- package/src/loadBalancer/configure/AzureLoadBalancerChoiceModal.tsx +46 -26
- package/src/loadBalancer/configure/AzureLoadBalancerModal.spec.tsx +658 -0
- package/src/loadBalancer/configure/AzureLoadBalancerModal.tsx +960 -0
- package/src/loadBalancer/details/azureLoadBalancerDetails.spec.tsx +470 -0
- package/src/loadBalancer/details/azureLoadBalancerDetails.tsx +412 -0
- package/src/loadBalancer/loadBalancer.transformer.js +83 -93
- package/src/pipeline/stages/AzureAccountRegionClusterSelector.tsx +238 -0
- package/src/pipeline/stages/bake/azureBakeStage.tsx +723 -0
- package/src/pipeline/stages/destroyAsg/azureDestroyAsgStage.tsx +128 -0
- package/src/pipeline/stages/disableAsg/azureDisableAsgStage.tsx +92 -0
- package/src/pipeline/stages/enableAsg/azureEnableAsgStage.tsx +87 -0
- package/src/routerConsumers.spec.tsx +69 -0
- package/src/securityGroup/configure/AzureSecurityGroupModal.spec.tsx +558 -0
- package/src/securityGroup/configure/AzureSecurityGroupModal.tsx +782 -0
- package/src/securityGroup/details/AzureSecurityGroupDetails.spec.tsx +291 -0
- package/src/securityGroup/details/AzureSecurityGroupDetails.tsx +354 -0
- package/src/securityGroup/securityGroup.reader.js +3 -13
- package/src/securityGroup/securityGroup.transformer.js +3 -13
- package/src/securityGroup/securityGroup.write.service.spec.ts +105 -0
- package/src/securityGroup/securityGroup.write.service.ts +73 -0
- package/src/serverGroup/configure/serverGroupCommandBuilder.service.js +167 -166
- package/src/serverGroup/configure/serverGroupCommandBuilder.service.spec.js +63 -0
- package/src/serverGroup/configure/serverGroupConfiguration.service.js +325 -309
- package/src/serverGroup/configure/serverGroupConfiguration.service.spec.js +57 -53
- package/src/serverGroup/configure/wizard/AzureCloneServerGroupModal.spec.tsx +758 -0
- package/src/serverGroup/configure/wizard/AzureCloneServerGroupModal.tsx +349 -0
- package/src/serverGroup/configure/wizard/pages/ServerGroupAdvancedSettings.tsx +208 -0
- package/src/serverGroup/configure/wizard/pages/ServerGroupBasicSettings.tsx +122 -0
- package/src/serverGroup/configure/wizard/pages/ServerGroupCapacityAndZones.tsx +80 -0
- package/src/serverGroup/configure/wizard/pages/ServerGroupHealthSettings.tsx +97 -0
- package/src/serverGroup/configure/wizard/pages/ServerGroupImageSettings.tsx +151 -0
- package/src/serverGroup/configure/wizard/pages/ServerGroupInstanceType.tsx +41 -0
- package/src/serverGroup/configure/wizard/pages/ServerGroupLoadBalancers.tsx +214 -0
- package/src/serverGroup/configure/wizard/pages/ServerGroupNetworkSettings.tsx +119 -0
- package/src/serverGroup/configure/wizard/pages/ServerGroupSecurityGroups.tsx +54 -0
- package/src/serverGroup/configure/wizard/pages/ServerGroupTags.tsx +40 -0
- package/src/serverGroup/configure/wizard/pages/common.tsx +72 -0
- package/src/serverGroup/configure/wizard/pages/index.ts +10 -0
- package/src/serverGroup/details/azureServerGroupDetails.spec.tsx +263 -0
- package/src/serverGroup/details/azureServerGroupDetails.tsx +318 -0
- package/src/serverGroup/details/rollback/RollbackServerGroupModal.tsx +24 -30
- package/src/serverGroup/serverGroup.transformer.js +11 -19
- package/src/serverGroup/serverGroup.transformer.spec.js +2 -6
- package/src/validation/applicationName.validator.js +14 -29
- package/dist/instance/details/instance.details.controller.d.ts +0 -2
- package/dist/loadBalancer/configure/createLoadBalancer.controller.d.ts +0 -2
- package/dist/loadBalancer/details/loadBalancerDetail.controller.d.ts +0 -2
- package/dist/pipeline/stages/bake/bakeExecutionDetails.controller.d.ts +0 -2
- package/dist/securityGroup/clone/cloneSecurityGroup.controller.d.ts +0 -2
- package/dist/securityGroup/configure/CreateSecurityGroupCtrl.d.ts +0 -2
- package/dist/securityGroup/configure/EditSecurityGroupCtrl.d.ts +0 -2
- package/dist/securityGroup/details/securityGroupDetail.controller.d.ts +0 -2
- package/dist/serverGroup/configure/serverGroup.configure.azure.module.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/CloneServerGroup.azure.controller.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/ServerGroupInstanceArchetype.controller.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/ServerGroupInstanceType.controller.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/advancedSettings/ServerGroupAdvancedSettings.controller.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/advancedSettings/advancedSettingsSelector.directive.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/basicSettings/ServerGroupBasicSettings.controller.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/basicSettings/image.regional.filter.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/capacity/capacitySelector.directive.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/healthSettings/ServerGroupHealthSettings.controller.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/healthSettings/healthSettingsSelector.directive.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/image/ServerGroupImageSettings.controller.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/image/imageSettingsSelector.directive.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/loadBalancers/ServerGroupLoadBalancers.controller.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/loadBalancers/serverGroupLoadBalancersSelector.directive.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/networkSettings/ServerGroupNetworkSettings.controller.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/networkSettings/ServerGroupNetworkSettingsSelector.directive.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/securityGroup/ServerGroupSecurityGroups.controller.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/securityGroup/serverGroupSecurityGroupsSelector.directive.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/tags/tagsSelector.directive.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/zones/zoneSelector.directive.d.ts +0 -2
- package/dist/serverGroup/details/serverGroup.details.module.d.ts +0 -2
- package/dist/serverGroup/details/serverGroupDetails.azure.controller.d.ts +0 -2
- package/src/instance/details/instance.details.controller.js +0 -371
- package/src/instance/details/instance.details.controller.spec.js +0 -129
- package/src/instance/details/instanceDetails.html +0 -43
- package/src/loadBalancer/configure/advancedSettings.html +0 -95
- package/src/loadBalancer/configure/createLoadBalancer.controller.js +0 -275
- package/src/loadBalancer/configure/createLoadBalancer.controller.spec.js +0 -39
- package/src/loadBalancer/configure/createLoadBalancer.html +0 -25
- package/src/loadBalancer/configure/createLoadBalancerProperties.html +0 -128
- package/src/loadBalancer/configure/editLoadBalancer.html +0 -26
- package/src/loadBalancer/configure/healthCheck.html +0 -74
- package/src/loadBalancer/configure/listeners.html +0 -50
- package/src/loadBalancer/details/loadBalancerDetail.controller.js +0 -181
- package/src/loadBalancer/details/loadBalancerDetail.controller.spec.js +0 -39
- package/src/loadBalancer/details/loadBalancerDetail.html +0 -128
- package/src/pipeline/stages/bake/azureBakeStage.js +0 -276
- package/src/pipeline/stages/bake/bakeExecutionDetails.controller.js +0 -40
- package/src/pipeline/stages/bake/bakeExecutionDetails.html +0 -50
- package/src/pipeline/stages/bake/bakeStage.html +0 -187
- package/src/pipeline/stages/destroyAsg/azureDestroyAsgStage.js +0 -73
- package/src/pipeline/stages/destroyAsg/destroyAsgStage.html +0 -9
- package/src/pipeline/stages/destroyAsg/destroyAsgStepLabel.html +0 -1
- package/src/pipeline/stages/disableAsg/azureDisableAsgStage.js +0 -65
- package/src/pipeline/stages/disableAsg/disableAsgStage.html +0 -11
- package/src/pipeline/stages/disableAsg/disableAsgStepLabel.html +0 -1
- package/src/pipeline/stages/enableAsg/azureEnableAsgStage.js +0 -70
- package/src/pipeline/stages/enableAsg/enableAsgStage.html +0 -11
- package/src/pipeline/stages/enableAsg/enableAsgStepLabel.html +0 -1
- package/src/securityGroup/clone/cloneSecurityGroup.controller.js +0 -162
- package/src/securityGroup/clone/cloneSecurityGroup.html +0 -8
- package/src/securityGroup/configure/CreateSecurityGroup.controller.spec.js +0 -78
- package/src/securityGroup/configure/CreateSecurityGroupCtrl.js +0 -265
- package/src/securityGroup/configure/EditSecurityGroupCtrl.js +0 -222
- package/src/securityGroup/configure/configSecurityGroup.mixin.controller.js +0 -262
- package/src/securityGroup/configure/createSecurityGroup.html +0 -20
- package/src/securityGroup/configure/createSecurityGroupIngress.html +0 -75
- package/src/securityGroup/configure/createSecurityGroupProperties.html +0 -88
- package/src/securityGroup/configure/editSecurityGroup.html +0 -19
- package/src/securityGroup/details/securityGroupDetail.controller.js +0 -142
- package/src/securityGroup/details/securityGroupDetail.html +0 -78
- package/src/securityGroup/securityGroup.write.service.js +0 -57
- package/src/serverGroup/configure/serverGroup.configure.azure.module.js +0 -47
- package/src/serverGroup/configure/wizard/CloneServerGroup.azure.controller.js +0 -247
- package/src/serverGroup/configure/wizard/ServerGroupInstanceArchetype.controller.js +0 -35
- package/src/serverGroup/configure/wizard/ServerGroupInstanceType.controller.js +0 -15
- package/src/serverGroup/configure/wizard/advancedSettings/ServerGroupAdvancedSettings.controller.js +0 -25
- package/src/serverGroup/configure/wizard/advancedSettings/advancedSettings.html +0 -5
- package/src/serverGroup/configure/wizard/advancedSettings/advancedSettingsSelector.directive.html +0 -138
- package/src/serverGroup/configure/wizard/advancedSettings/advancedSettingsSelector.directive.js +0 -43
- package/src/serverGroup/configure/wizard/basicSettings/ServerGroupBasicSettings.controller.js +0 -71
- package/src/serverGroup/configure/wizard/basicSettings/basicSettings.html +0 -131
- package/src/serverGroup/configure/wizard/basicSettings/image.regional.filter.js +0 -15
- package/src/serverGroup/configure/wizard/basicSettings/image.regional.filter.spec.js +0 -42
- package/src/serverGroup/configure/wizard/capacity/capacity.html +0 -5
- package/src/serverGroup/configure/wizard/capacity/capacitySelector.directive.html +0 -20
- package/src/serverGroup/configure/wizard/capacity/capacitySelector.directive.js +0 -21
- package/src/serverGroup/configure/wizard/capacity/zones.html +0 -5
- package/src/serverGroup/configure/wizard/healthSettings/ServerGroupHealthSettings.controller.js +0 -38
- package/src/serverGroup/configure/wizard/healthSettings/healthSettings.html +0 -5
- package/src/serverGroup/configure/wizard/healthSettings/healthSettingsSelector.directive.html +0 -32
- package/src/serverGroup/configure/wizard/healthSettings/healthSettingsSelector.directive.js +0 -22
- package/src/serverGroup/configure/wizard/image/ServerGroupImageSettings.controller.js +0 -34
- package/src/serverGroup/configure/wizard/image/imageSettings.html +0 -5
- package/src/serverGroup/configure/wizard/image/imageSettingsSelector.directive.html +0 -33
- package/src/serverGroup/configure/wizard/image/imageSettingsSelector.directive.js +0 -22
- package/src/serverGroup/configure/wizard/instanceArchetype.html +0 -33
- package/src/serverGroup/configure/wizard/instanceType/instanceType.html +0 -10
- package/src/serverGroup/configure/wizard/instanceType.html +0 -33
- package/src/serverGroup/configure/wizard/loadBalancers/ServerGroupLoadBalancers.controller.js +0 -137
- package/src/serverGroup/configure/wizard/loadBalancers/loadBalancers.html +0 -3
- package/src/serverGroup/configure/wizard/loadBalancers/serverGroupLoadBalancersSelector.directive.html +0 -41
- package/src/serverGroup/configure/wizard/loadBalancers/serverGroupLoadBalancersSelector.directive.js +0 -22
- package/src/serverGroup/configure/wizard/networkSettings/ServerGroupNetworkSettings.controller.js +0 -44
- package/src/serverGroup/configure/wizard/networkSettings/ServerGroupNetworkSettingsSelector.directive.html +0 -54
- package/src/serverGroup/configure/wizard/networkSettings/ServerGroupNetworkSettingsSelector.directive.js +0 -19
- package/src/serverGroup/configure/wizard/networkSettings/networkSettings.html +0 -3
- package/src/serverGroup/configure/wizard/securityGroup/ServerGroupSecurityGroups.controller.js +0 -28
- package/src/serverGroup/configure/wizard/securityGroup/securityGroups.html +0 -3
- package/src/serverGroup/configure/wizard/securityGroup/serverGroupSecurityGroupsSelector.directive.html +0 -40
- package/src/serverGroup/configure/wizard/securityGroup/serverGroupSecurityGroupsSelector.directive.js +0 -38
- package/src/serverGroup/configure/wizard/serverGroupWizard.html +0 -61
- package/src/serverGroup/configure/wizard/tags/tags.html +0 -5
- package/src/serverGroup/configure/wizard/tags/tagsSelector.directive.html +0 -16
- package/src/serverGroup/configure/wizard/tags/tagsSelector.directive.js +0 -30
- package/src/serverGroup/configure/wizard/templateSelection.html +0 -9
- package/src/serverGroup/configure/wizard/zones/zoneSelector.directive.html +0 -21
- package/src/serverGroup/configure/wizard/zones/zoneSelector.directive.js +0 -28
- package/src/serverGroup/details/serverGroup.details.module.js +0 -11
- package/src/serverGroup/details/serverGroupDetails.azure.controller.js +0 -260
- package/src/serverGroup/details/serverGroupDetails.html +0 -98
- package/src/subnet/subnetSelectField.directive.html +0 -28
- package/src/subnet/subnetSelectField.directive.js +0 -35
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { shallow } from 'enzyme';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { MenuItem } from 'react-bootstrap';
|
|
4
|
+
|
|
5
|
+
import { AccountTag, CollapsibleSection, ConfirmationModalService } from '@spinnaker/core';
|
|
6
|
+
|
|
7
|
+
import { AzureSecurityGroupModal } from '../configure/AzureSecurityGroupModal';
|
|
8
|
+
import { AzureSecurityGroupWriter } from '../securityGroup.write.service';
|
|
9
|
+
import {
|
|
10
|
+
AzureSecurityGroupActions,
|
|
11
|
+
AzureSecurityGroupDetailsComponent as AzureSecurityGroupDetails,
|
|
12
|
+
AzureSecurityGroupInformationSection,
|
|
13
|
+
AzureSecurityGroupRulesSection,
|
|
14
|
+
} from './AzureSecurityGroupDetails';
|
|
15
|
+
|
|
16
|
+
describe('AzureSecurityGroupDetails', () => {
|
|
17
|
+
const resolvedSecurityGroup = {
|
|
18
|
+
accountId: 'test-account',
|
|
19
|
+
name: 'fnord-sg',
|
|
20
|
+
provider: 'azure',
|
|
21
|
+
region: 'westus',
|
|
22
|
+
vpcId: 'vnet-1',
|
|
23
|
+
} as any;
|
|
24
|
+
|
|
25
|
+
function app() {
|
|
26
|
+
return {
|
|
27
|
+
name: 'fnord',
|
|
28
|
+
getDataSource: () => ({ ready: () => Promise.resolve(), onRefresh: () => jasmine.createSpy('unsubscribe') }),
|
|
29
|
+
securityGroups: { refresh: jasmine.createSpy('refresh') },
|
|
30
|
+
} as any;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function securityGroup() {
|
|
34
|
+
return {
|
|
35
|
+
account: 'test-account',
|
|
36
|
+
accountId: 'test-account',
|
|
37
|
+
name: 'fnord-sg',
|
|
38
|
+
region: 'westus',
|
|
39
|
+
securityRules: [
|
|
40
|
+
{
|
|
41
|
+
name: 'allow-web',
|
|
42
|
+
access: 'Allow',
|
|
43
|
+
destinationAddressPrefix: '*',
|
|
44
|
+
direction: 'Inbound',
|
|
45
|
+
priority: 100,
|
|
46
|
+
protocol: 'Tcp',
|
|
47
|
+
sourceAddressPrefixes: ['10.0.0.0/24', '192.168.0.0/24'],
|
|
48
|
+
sourcePortRange: '*',
|
|
49
|
+
destinationPortRanges: ['80', '443'],
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
vpcId: 'vnet-1',
|
|
53
|
+
} as any;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
it('closes missing details through the injected state service', () => {
|
|
57
|
+
const stateService = { go: jasmine.createSpy('go') };
|
|
58
|
+
const component = new AzureSecurityGroupDetails({
|
|
59
|
+
app: app(),
|
|
60
|
+
resolvedSecurityGroup,
|
|
61
|
+
router: {},
|
|
62
|
+
stateParams: {},
|
|
63
|
+
stateService,
|
|
64
|
+
} as any);
|
|
65
|
+
|
|
66
|
+
(component as any).autoClose();
|
|
67
|
+
|
|
68
|
+
expect(stateService.go).toHaveBeenCalledWith('^');
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('loads details with the core security group reader and renders basic sections', async () => {
|
|
72
|
+
const securityGroupReader = {
|
|
73
|
+
getSecurityGroupDetails: jasmine
|
|
74
|
+
.createSpy('getSecurityGroupDetails')
|
|
75
|
+
.and.returnValue(Promise.resolve(securityGroup())),
|
|
76
|
+
};
|
|
77
|
+
const wrapper = shallow(
|
|
78
|
+
<AzureSecurityGroupDetails
|
|
79
|
+
app={app()}
|
|
80
|
+
resolvedSecurityGroup={resolvedSecurityGroup}
|
|
81
|
+
securityGroupReader={securityGroupReader as any}
|
|
82
|
+
/>,
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
await Promise.resolve();
|
|
86
|
+
await Promise.resolve();
|
|
87
|
+
wrapper.update();
|
|
88
|
+
|
|
89
|
+
expect(securityGroupReader.getSecurityGroupDetails).toHaveBeenCalledWith(
|
|
90
|
+
jasmine.anything(),
|
|
91
|
+
'test-account',
|
|
92
|
+
'azure',
|
|
93
|
+
'westus',
|
|
94
|
+
'vnet-1',
|
|
95
|
+
'fnord-sg',
|
|
96
|
+
);
|
|
97
|
+
expect(wrapper.find('h3').text()).toContain('fnord-sg');
|
|
98
|
+
expect(wrapper.find(AzureSecurityGroupActions).prop('securityGroup')).toEqual(securityGroup());
|
|
99
|
+
expect(wrapper.find(AzureSecurityGroupRulesSection).prop('securityGroup')).toEqual(securityGroup());
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('renders Azure security rules with normalized port and source values', () => {
|
|
103
|
+
const wrapper = shallow(<AzureSecurityGroupRulesSection securityGroup={securityGroup()} />);
|
|
104
|
+
const sectionContent = shallow(<div>{wrapper.find(CollapsibleSection).prop('children')}</div>);
|
|
105
|
+
const text = sectionContent.text();
|
|
106
|
+
|
|
107
|
+
expect(text).toContain('allow-web');
|
|
108
|
+
expect(text).toContain('100');
|
|
109
|
+
expect(text).toContain('10.0.0.0/24, 192.168.0.0/24');
|
|
110
|
+
expect(text).toContain('*');
|
|
111
|
+
expect(text).toContain('80, 443');
|
|
112
|
+
expect(text).toContain('Inbound');
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('renders legacy information fields from the Azure details panel', () => {
|
|
116
|
+
const wrapper = shallow(
|
|
117
|
+
<AzureSecurityGroupInformationSection
|
|
118
|
+
securityGroup={
|
|
119
|
+
{
|
|
120
|
+
accountName: 'prod-account',
|
|
121
|
+
description: 'frontend ingress',
|
|
122
|
+
id: 'nsg-resource-id',
|
|
123
|
+
region: 'westus',
|
|
124
|
+
vpcId: 'vnet-1',
|
|
125
|
+
} as any
|
|
126
|
+
}
|
|
127
|
+
/>,
|
|
128
|
+
);
|
|
129
|
+
const sectionContent = shallow(<div>{wrapper.find(CollapsibleSection).prop('children')}</div>);
|
|
130
|
+
const text = sectionContent.text();
|
|
131
|
+
|
|
132
|
+
expect(text).toContain('nsg-resource-id');
|
|
133
|
+
expect(sectionContent.find(AccountTag).prop('account')).toBe('prod-account');
|
|
134
|
+
expect(text).toContain('westus');
|
|
135
|
+
expect(text).toContain('frontend ingress');
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('renders legacy details model fields for security rule source and ports', () => {
|
|
139
|
+
const wrapper = shallow(
|
|
140
|
+
<AzureSecurityGroupRulesSection
|
|
141
|
+
securityGroup={
|
|
142
|
+
{
|
|
143
|
+
securityRules: [
|
|
144
|
+
{
|
|
145
|
+
name: 'allow-web',
|
|
146
|
+
destinationPortRangeModel: '8080, 8443',
|
|
147
|
+
sourceAddressPrefixModel: '10.0.0.0/24, 192.168.0.0/24',
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
} as any
|
|
151
|
+
}
|
|
152
|
+
/>,
|
|
153
|
+
);
|
|
154
|
+
const sectionContent = shallow(<div>{wrapper.find(CollapsibleSection).prop('children')}</div>);
|
|
155
|
+
const text = sectionContent.text();
|
|
156
|
+
|
|
157
|
+
expect(text).toContain('10.0.0.0/24, 192.168.0.0/24');
|
|
158
|
+
expect(text).toContain('8080, 8443');
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('renders Azure security rules sorted by priority', () => {
|
|
162
|
+
const wrapper = shallow(
|
|
163
|
+
<AzureSecurityGroupRulesSection
|
|
164
|
+
securityGroup={
|
|
165
|
+
{
|
|
166
|
+
securityRules: [
|
|
167
|
+
{ name: 'second', priority: 200, destinationPortRange: '443', sourceAddressPrefix: '*' },
|
|
168
|
+
{ name: 'first', priority: 100, destinationPortRange: '80', sourceAddressPrefix: '*' },
|
|
169
|
+
],
|
|
170
|
+
} as any
|
|
171
|
+
}
|
|
172
|
+
/>,
|
|
173
|
+
);
|
|
174
|
+
const sectionContent = shallow(<div>{wrapper.find(CollapsibleSection).prop('children')}</div>);
|
|
175
|
+
const ruleNames = sectionContent.find('tbody tr').map((row) => row.find('td').at(1).text());
|
|
176
|
+
|
|
177
|
+
expect(ruleNames).toEqual(['first', 'second']);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('reloads when coordinates change and ignores stale responses', async () => {
|
|
181
|
+
let resolveFirst: (value: any) => void;
|
|
182
|
+
let resolveSecond: (value: any) => void;
|
|
183
|
+
const securityGroupReader = {
|
|
184
|
+
getSecurityGroupDetails: jasmine
|
|
185
|
+
.createSpy('getSecurityGroupDetails')
|
|
186
|
+
.and.callFake(
|
|
187
|
+
(_app: any, _account: string, _provider: string, _region: string, _vpcId: string, name: string) => {
|
|
188
|
+
if (name === 'fnord-sg') {
|
|
189
|
+
return new Promise((resolve) => {
|
|
190
|
+
resolveFirst = resolve;
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
return new Promise((resolve) => {
|
|
194
|
+
resolveSecond = resolve;
|
|
195
|
+
});
|
|
196
|
+
},
|
|
197
|
+
),
|
|
198
|
+
};
|
|
199
|
+
const wrapper = shallow(
|
|
200
|
+
<AzureSecurityGroupDetails
|
|
201
|
+
app={app()}
|
|
202
|
+
resolvedSecurityGroup={resolvedSecurityGroup}
|
|
203
|
+
securityGroupReader={securityGroupReader as any}
|
|
204
|
+
/>,
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
await Promise.resolve();
|
|
208
|
+
wrapper.setProps({ resolvedSecurityGroup: { ...resolvedSecurityGroup, name: 'other-sg' } });
|
|
209
|
+
await Promise.resolve();
|
|
210
|
+
resolveSecond({ ...securityGroup(), name: 'other-sg' });
|
|
211
|
+
await Promise.resolve();
|
|
212
|
+
resolveFirst(securityGroup());
|
|
213
|
+
await Promise.resolve();
|
|
214
|
+
wrapper.update();
|
|
215
|
+
|
|
216
|
+
expect(securityGroupReader.getSecurityGroupDetails.calls.count()).toBe(2);
|
|
217
|
+
expect(wrapper.find('h3').text()).toContain('other-sg');
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
it('auto-closes when the details response is empty', async () => {
|
|
221
|
+
const autoClose = jasmine.createSpy('autoClose');
|
|
222
|
+
const securityGroupReader = {
|
|
223
|
+
getSecurityGroupDetails: jasmine.createSpy('getSecurityGroupDetails').and.returnValue(Promise.resolve({})),
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
shallow(
|
|
227
|
+
<AzureSecurityGroupDetails
|
|
228
|
+
app={app()}
|
|
229
|
+
autoClose={autoClose}
|
|
230
|
+
resolvedSecurityGroup={resolvedSecurityGroup}
|
|
231
|
+
securityGroupReader={securityGroupReader as any}
|
|
232
|
+
/>,
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
await Promise.resolve();
|
|
236
|
+
await Promise.resolve();
|
|
237
|
+
|
|
238
|
+
expect(autoClose).toHaveBeenCalled();
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
it('opens edit, clone, and delete actions', () => {
|
|
242
|
+
spyOn(AzureSecurityGroupModal, 'show');
|
|
243
|
+
spyOn(ConfirmationModalService, 'confirm');
|
|
244
|
+
spyOn(AzureSecurityGroupWriter, 'deleteSecurityGroup').and.returnValue(Promise.resolve({} as any));
|
|
245
|
+
const wrapper = shallow(<AzureSecurityGroupActions app={app()} securityGroup={securityGroup()} />);
|
|
246
|
+
|
|
247
|
+
wrapper.find(MenuItem).at(0).prop('onClick')({} as any);
|
|
248
|
+
wrapper.find(MenuItem).at(1).prop('onClick')({} as any);
|
|
249
|
+
wrapper.find(MenuItem).at(2).prop('onClick')({} as any);
|
|
250
|
+
|
|
251
|
+
expect(AzureSecurityGroupModal.show).toHaveBeenCalledWith(jasmine.objectContaining({ mode: 'edit' }));
|
|
252
|
+
expect(AzureSecurityGroupModal.show).toHaveBeenCalledWith(jasmine.objectContaining({ mode: 'clone' }));
|
|
253
|
+
expect(ConfirmationModalService.confirm).toHaveBeenCalled();
|
|
254
|
+
const confirmArgs = (ConfirmationModalService.confirm as jasmine.Spy).calls.mostRecent().args[0];
|
|
255
|
+
confirmArgs.submitMethod();
|
|
256
|
+
expect(AzureSecurityGroupWriter.deleteSecurityGroup).toHaveBeenCalledWith(
|
|
257
|
+
securityGroup(),
|
|
258
|
+
jasmine.anything(),
|
|
259
|
+
jasmine.objectContaining({ cloudProvider: 'azure', vpcId: 'vnet-1' }),
|
|
260
|
+
);
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
it('uses resolved coordinates when deleting fetched details without account identity', () => {
|
|
264
|
+
spyOn(ConfirmationModalService, 'confirm');
|
|
265
|
+
spyOn(AzureSecurityGroupWriter, 'deleteSecurityGroup').and.returnValue(Promise.resolve({} as any));
|
|
266
|
+
const fetchedDetails = {
|
|
267
|
+
name: 'fnord-sg',
|
|
268
|
+
region: 'westus',
|
|
269
|
+
securityRules: [],
|
|
270
|
+
vpcId: 'vnet-1',
|
|
271
|
+
} as any;
|
|
272
|
+
const wrapper = shallow(
|
|
273
|
+
React.createElement(AzureSecurityGroupActions as any, {
|
|
274
|
+
app: app(),
|
|
275
|
+
resolvedSecurityGroup,
|
|
276
|
+
securityGroup: fetchedDetails,
|
|
277
|
+
}),
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
wrapper.find(MenuItem).at(2).prop('onClick')({} as any);
|
|
281
|
+
|
|
282
|
+
const confirmArgs = (ConfirmationModalService.confirm as jasmine.Spy).calls.mostRecent().args[0];
|
|
283
|
+
expect(confirmArgs.account).toBe('test-account');
|
|
284
|
+
confirmArgs.submitMethod();
|
|
285
|
+
expect(AzureSecurityGroupWriter.deleteSecurityGroup).toHaveBeenCalledWith(
|
|
286
|
+
jasmine.objectContaining({ accountId: 'test-account', name: 'fnord-sg', region: 'westus' }),
|
|
287
|
+
jasmine.anything(),
|
|
288
|
+
jasmine.objectContaining({ cloudProvider: 'azure', vpcId: 'vnet-1' }),
|
|
289
|
+
);
|
|
290
|
+
});
|
|
291
|
+
});
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Dropdown, MenuItem } from 'react-bootstrap';
|
|
3
|
+
|
|
4
|
+
import type {
|
|
5
|
+
Application,
|
|
6
|
+
IOverridableProps,
|
|
7
|
+
IRouterInjectedProps,
|
|
8
|
+
ISecurityGroupDetail,
|
|
9
|
+
SecurityGroupReader,
|
|
10
|
+
} from '@spinnaker/core';
|
|
11
|
+
import {
|
|
12
|
+
AccountTag,
|
|
13
|
+
CollapsibleSection,
|
|
14
|
+
ConfirmationModalService,
|
|
15
|
+
DeckRuntimeContext,
|
|
16
|
+
withRouter,
|
|
17
|
+
} from '@spinnaker/core';
|
|
18
|
+
|
|
19
|
+
import { AzureSecurityGroupModal } from '../configure/AzureSecurityGroupModal';
|
|
20
|
+
import { AzureSecurityGroupWriter } from '../securityGroup.write.service';
|
|
21
|
+
|
|
22
|
+
interface IAzureResolvedSecurityGroup {
|
|
23
|
+
accountId?: string;
|
|
24
|
+
name: string;
|
|
25
|
+
provider?: string;
|
|
26
|
+
region: string;
|
|
27
|
+
vpcId?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface IAzureSecurityGroupDetailsProps extends IOverridableProps {
|
|
31
|
+
app: Application;
|
|
32
|
+
autoClose?: () => void;
|
|
33
|
+
resolvedSecurityGroup: IAzureResolvedSecurityGroup;
|
|
34
|
+
securityGroupReader?: SecurityGroupReader;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
interface IAzureSecurityGroupDetailsState {
|
|
38
|
+
loading: boolean;
|
|
39
|
+
securityGroup?: ISecurityGroupDetail & Record<string, any>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface IAzureSecurityGroupSectionProps {
|
|
43
|
+
securityGroup: ISecurityGroupDetail & Record<string, any>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export class AzureSecurityGroupDetailsComponent extends React.Component<
|
|
47
|
+
IAzureSecurityGroupDetailsProps & IRouterInjectedProps,
|
|
48
|
+
IAzureSecurityGroupDetailsState
|
|
49
|
+
> {
|
|
50
|
+
public static contextType = DeckRuntimeContext;
|
|
51
|
+
public declare context: React.ContextType<typeof DeckRuntimeContext>;
|
|
52
|
+
|
|
53
|
+
public state: IAzureSecurityGroupDetailsState = { loading: true };
|
|
54
|
+
|
|
55
|
+
private isUnmounted = false;
|
|
56
|
+
private loadRequestId = 0;
|
|
57
|
+
private unsubscribeFromRefresh: () => void;
|
|
58
|
+
|
|
59
|
+
public componentDidMount(): void {
|
|
60
|
+
const dataSource = this.props.app.getDataSource?.('securityGroups');
|
|
61
|
+
if (!dataSource) {
|
|
62
|
+
this.loadSecurityGroup();
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
dataSource.ready().then(() => {
|
|
67
|
+
if (this.isUnmounted) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
this.loadSecurityGroup();
|
|
71
|
+
this.unsubscribeFromRefresh = dataSource.onRefresh(this.loadSecurityGroup);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public componentWillUnmount(): void {
|
|
76
|
+
this.isUnmounted = true;
|
|
77
|
+
if (this.unsubscribeFromRefresh) {
|
|
78
|
+
this.unsubscribeFromRefresh();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public componentDidUpdate(prevProps: IAzureSecurityGroupDetailsProps): void {
|
|
83
|
+
if (this.getCoordinatesKey(prevProps) !== this.getCoordinatesKey(this.props)) {
|
|
84
|
+
this.loadSecurityGroup();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private getCoordinatesKey(props: IAzureSecurityGroupDetailsProps): string {
|
|
89
|
+
const { accountId, name, region, vpcId } = props.resolvedSecurityGroup;
|
|
90
|
+
return [accountId, region, vpcId || '', name].join(':');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
private getSecurityGroupReader(): SecurityGroupReader {
|
|
94
|
+
return this.props.securityGroupReader || this.context.services.securityGroupReader;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private loadSecurityGroup = (): void => {
|
|
98
|
+
const { app, resolvedSecurityGroup } = this.props;
|
|
99
|
+
const requestId = ++this.loadRequestId;
|
|
100
|
+
this.setState({ loading: true });
|
|
101
|
+
this.getSecurityGroupReader()
|
|
102
|
+
.getSecurityGroupDetails(
|
|
103
|
+
app,
|
|
104
|
+
resolvedSecurityGroup.accountId,
|
|
105
|
+
'azure',
|
|
106
|
+
resolvedSecurityGroup.region,
|
|
107
|
+
resolvedSecurityGroup.vpcId || '',
|
|
108
|
+
resolvedSecurityGroup.name,
|
|
109
|
+
)
|
|
110
|
+
.then((securityGroup: ISecurityGroupDetail & Record<string, any>) => {
|
|
111
|
+
if (this.isUnmounted || requestId !== this.loadRequestId) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (!securityGroup || Object.keys(securityGroup).length === 0) {
|
|
115
|
+
this.autoClose();
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
this.setState({ loading: false, securityGroup });
|
|
119
|
+
})
|
|
120
|
+
.catch(() => {
|
|
121
|
+
if (requestId === this.loadRequestId) {
|
|
122
|
+
this.autoClose();
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
private autoClose = (): void => {
|
|
128
|
+
if (this.isUnmounted) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (this.props.autoClose) {
|
|
132
|
+
this.props.autoClose();
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
this.props.stateService.go('^');
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
private closeDetails = (): void => {
|
|
139
|
+
this.props.stateService.go('^');
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
public render(): JSX.Element {
|
|
143
|
+
const { app } = this.props;
|
|
144
|
+
const { loading, securityGroup } = this.state;
|
|
145
|
+
|
|
146
|
+
if (loading || !securityGroup) {
|
|
147
|
+
return (
|
|
148
|
+
<div className="details-panel">
|
|
149
|
+
<div className="header">
|
|
150
|
+
<div className="close-button">
|
|
151
|
+
<a className="btn btn-link" onClick={this.closeDetails}>
|
|
152
|
+
<span className="glyphicon glyphicon-remove" />
|
|
153
|
+
</a>
|
|
154
|
+
</div>
|
|
155
|
+
<h4 className="text-center">Loading...</h4>
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return (
|
|
162
|
+
<div className="details-panel">
|
|
163
|
+
<div className="header">
|
|
164
|
+
<div className="close-button">
|
|
165
|
+
<a className="btn btn-link" onClick={this.closeDetails}>
|
|
166
|
+
<span className="glyphicon glyphicon-remove" />
|
|
167
|
+
</a>
|
|
168
|
+
</div>
|
|
169
|
+
<div className="header-text horizontal middle">
|
|
170
|
+
<h3>{securityGroup.name}</h3>
|
|
171
|
+
</div>
|
|
172
|
+
<div className="actions">
|
|
173
|
+
<AzureSecurityGroupActions
|
|
174
|
+
app={app}
|
|
175
|
+
resolvedSecurityGroup={this.props.resolvedSecurityGroup}
|
|
176
|
+
securityGroup={securityGroup}
|
|
177
|
+
/>
|
|
178
|
+
</div>
|
|
179
|
+
</div>
|
|
180
|
+
<div className="content">
|
|
181
|
+
<AzureSecurityGroupInformationSection securityGroup={securityGroup} />
|
|
182
|
+
<AzureSecurityGroupRulesSection securityGroup={securityGroup} />
|
|
183
|
+
</div>
|
|
184
|
+
</div>
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export const AzureSecurityGroupDetails = withRouter(AzureSecurityGroupDetailsComponent);
|
|
190
|
+
|
|
191
|
+
function withResolvedCoordinates(securityGroup: any, resolvedSecurityGroup?: IAzureResolvedSecurityGroup): any {
|
|
192
|
+
if (!resolvedSecurityGroup) {
|
|
193
|
+
return securityGroup;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const accountId =
|
|
197
|
+
securityGroup.accountId ||
|
|
198
|
+
securityGroup.account ||
|
|
199
|
+
securityGroup.accountName ||
|
|
200
|
+
securityGroup.credentials ||
|
|
201
|
+
resolvedSecurityGroup.accountId;
|
|
202
|
+
const name = securityGroup.name || resolvedSecurityGroup.name;
|
|
203
|
+
const region = securityGroup.region || resolvedSecurityGroup.region;
|
|
204
|
+
const vpcId = securityGroup.vpcId || resolvedSecurityGroup.vpcId;
|
|
205
|
+
|
|
206
|
+
if (
|
|
207
|
+
accountId === securityGroup.accountId &&
|
|
208
|
+
name === securityGroup.name &&
|
|
209
|
+
region === securityGroup.region &&
|
|
210
|
+
vpcId === securityGroup.vpcId
|
|
211
|
+
) {
|
|
212
|
+
return securityGroup;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return { ...securityGroup, accountId, name, region, vpcId };
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export function AzureSecurityGroupActions({
|
|
219
|
+
app,
|
|
220
|
+
resolvedSecurityGroup,
|
|
221
|
+
securityGroup,
|
|
222
|
+
}: {
|
|
223
|
+
app: Application;
|
|
224
|
+
resolvedSecurityGroup?: IAzureResolvedSecurityGroup;
|
|
225
|
+
securityGroup: any;
|
|
226
|
+
}) {
|
|
227
|
+
const securityGroupWithCoordinates = withResolvedCoordinates(securityGroup, resolvedSecurityGroup);
|
|
228
|
+
const editSecurityGroup = (): void => {
|
|
229
|
+
AzureSecurityGroupModal.show({ app, mode: 'edit', securityGroup: securityGroupWithCoordinates });
|
|
230
|
+
};
|
|
231
|
+
const cloneSecurityGroup = (): void => {
|
|
232
|
+
AzureSecurityGroupModal.show({ app, mode: 'clone', securityGroup: securityGroupWithCoordinates });
|
|
233
|
+
};
|
|
234
|
+
const deleteSecurityGroup = (): void => {
|
|
235
|
+
ConfirmationModalService.confirm({
|
|
236
|
+
header: `Really delete ${securityGroupWithCoordinates.name}?`,
|
|
237
|
+
buttonText: `Delete ${securityGroupWithCoordinates.name}`,
|
|
238
|
+
account: securityGroupWithCoordinates.accountId || securityGroupWithCoordinates.account,
|
|
239
|
+
taskMonitorConfig: {
|
|
240
|
+
application: app,
|
|
241
|
+
title: `Deleting ${securityGroupWithCoordinates.name}`,
|
|
242
|
+
},
|
|
243
|
+
submitMethod: () =>
|
|
244
|
+
AzureSecurityGroupWriter.deleteSecurityGroup(securityGroupWithCoordinates, app, {
|
|
245
|
+
cloudProvider: 'azure',
|
|
246
|
+
vpcId: securityGroupWithCoordinates.vpcId,
|
|
247
|
+
}),
|
|
248
|
+
});
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
return (
|
|
252
|
+
<Dropdown className="dropdown" id="azure-security-group-actions-dropdown">
|
|
253
|
+
<Dropdown.Toggle className="btn btn-sm btn-primary dropdown-toggle">Security Group Actions</Dropdown.Toggle>
|
|
254
|
+
<Dropdown.Menu>
|
|
255
|
+
<MenuItem onClick={editSecurityGroup}>Edit Inbound Rules</MenuItem>
|
|
256
|
+
<MenuItem onClick={cloneSecurityGroup}>Clone Security Group</MenuItem>
|
|
257
|
+
<MenuItem onClick={deleteSecurityGroup}>Delete Security Group</MenuItem>
|
|
258
|
+
</Dropdown.Menu>
|
|
259
|
+
</Dropdown>
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export function AzureSecurityGroupInformationSection({ securityGroup }: IAzureSecurityGroupSectionProps) {
|
|
264
|
+
return (
|
|
265
|
+
<CollapsibleSection heading="Information" defaultExpanded={true}>
|
|
266
|
+
<dl className="dl-horizontal dl-narrow">
|
|
267
|
+
<dt>ID</dt>
|
|
268
|
+
<dd>{securityGroup.id || '-'}</dd>
|
|
269
|
+
<dt>Account</dt>
|
|
270
|
+
<dd>
|
|
271
|
+
<AccountTag account={securityGroup.accountId || securityGroup.accountName || securityGroup.account} />
|
|
272
|
+
</dd>
|
|
273
|
+
<dt>Region</dt>
|
|
274
|
+
<dd>{securityGroup.region}</dd>
|
|
275
|
+
<dt>Description:</dt>
|
|
276
|
+
<dd>{securityGroup.description || '-'}</dd>
|
|
277
|
+
<dt>VNet</dt>
|
|
278
|
+
<dd>{securityGroup.vpcId || '-'}</dd>
|
|
279
|
+
</dl>
|
|
280
|
+
</CollapsibleSection>
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function joinRuleValues(...values: any[]): string {
|
|
285
|
+
for (const value of values) {
|
|
286
|
+
if (Array.isArray(value) && value.length) {
|
|
287
|
+
return value.join(', ');
|
|
288
|
+
}
|
|
289
|
+
if (typeof value === 'string' && value.trim()) {
|
|
290
|
+
return value.trim();
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return '-';
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
function ruleSources(rule: any): string {
|
|
297
|
+
return joinRuleValues(
|
|
298
|
+
rule.sourceAddressPrefixModel,
|
|
299
|
+
rule.sourceAddressPrefixes,
|
|
300
|
+
rule.sourceAddressPrefix,
|
|
301
|
+
rule.sourceIPCIDRRanges,
|
|
302
|
+
rule.sourceCidrs,
|
|
303
|
+
);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
function rulePorts(rule: any): string {
|
|
307
|
+
return joinRuleValues(
|
|
308
|
+
rule.destinationPortRangeModel,
|
|
309
|
+
rule.destinationPortRanges,
|
|
310
|
+
rule.destinationPortRange,
|
|
311
|
+
rule.destPortRanges,
|
|
312
|
+
rule.destinationPorts,
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export function AzureSecurityGroupRulesSection({ securityGroup }: IAzureSecurityGroupSectionProps) {
|
|
317
|
+
const rules = (securityGroup.securityRules || securityGroup.inboundRules || [])
|
|
318
|
+
.slice()
|
|
319
|
+
.sort((a: any, b: any) => (a.priority ?? Number.MAX_SAFE_INTEGER) - (b.priority ?? Number.MAX_SAFE_INTEGER));
|
|
320
|
+
return (
|
|
321
|
+
<CollapsibleSection heading="Inbound Rules" defaultExpanded={true}>
|
|
322
|
+
<table className="table table-condensed">
|
|
323
|
+
<thead>
|
|
324
|
+
<tr>
|
|
325
|
+
<th>Priority</th>
|
|
326
|
+
<th>Name</th>
|
|
327
|
+
<th>Source</th>
|
|
328
|
+
<th>Source Port</th>
|
|
329
|
+
<th>Destination</th>
|
|
330
|
+
<th>Ports</th>
|
|
331
|
+
<th>Protocol</th>
|
|
332
|
+
<th>Access</th>
|
|
333
|
+
<th>Direction</th>
|
|
334
|
+
</tr>
|
|
335
|
+
</thead>
|
|
336
|
+
<tbody>
|
|
337
|
+
{rules.map((rule: any, index: number) => (
|
|
338
|
+
<tr key={rule.name || index}>
|
|
339
|
+
<td>{rule.priority || '-'}</td>
|
|
340
|
+
<td>{rule.name || '-'}</td>
|
|
341
|
+
<td>{ruleSources(rule)}</td>
|
|
342
|
+
<td>{rule.sourcePortRange || '-'}</td>
|
|
343
|
+
<td>{rule.destinationAddressPrefix || '-'}</td>
|
|
344
|
+
<td>{rulePorts(rule)}</td>
|
|
345
|
+
<td>{rule.protocol || '-'}</td>
|
|
346
|
+
<td>{rule.access || '-'}</td>
|
|
347
|
+
<td>{rule.direction || '-'}</td>
|
|
348
|
+
</tr>
|
|
349
|
+
))}
|
|
350
|
+
</tbody>
|
|
351
|
+
</table>
|
|
352
|
+
</CollapsibleSection>
|
|
353
|
+
);
|
|
354
|
+
}
|
|
@@ -1,17 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { module } from 'angular';
|
|
4
|
-
|
|
5
|
-
export const AZURE_SECURITYGROUP_SECURITYGROUP_READER = 'spinnaker.azure.securityGroup.reader';
|
|
6
|
-
export const name = AZURE_SECURITYGROUP_SECURITYGROUP_READER; // for backwards compatibility
|
|
7
|
-
module(AZURE_SECURITYGROUP_SECURITYGROUP_READER, []).factory('azureSecurityGroupReader', function () {
|
|
8
|
-
function resolveIndexedSecurityGroup(indexedSecurityGroups, container, securityGroupId) {
|
|
1
|
+
export class AzureSecurityGroupReader {
|
|
2
|
+
resolveIndexedSecurityGroup(indexedSecurityGroups, container, securityGroupId) {
|
|
9
3
|
//hack to get around securityGroupId not matching id in indexedSecurityGroups.
|
|
10
4
|
const temp = securityGroupId.split('/');
|
|
11
5
|
return indexedSecurityGroups[container.account][container.region][temp[temp.length - 1]];
|
|
12
6
|
}
|
|
13
|
-
|
|
14
|
-
return {
|
|
15
|
-
resolveIndexedSecurityGroup: resolveIndexedSecurityGroup,
|
|
16
|
-
};
|
|
17
|
-
});
|
|
7
|
+
}
|
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export const AZURE_SECURITYGROUP_SECURITYGROUP_TRANSFORMER = 'spinnaker.azure.securityGroup.transformer';
|
|
6
|
-
export const name = AZURE_SECURITYGROUP_SECURITYGROUP_TRANSFORMER; // for backwards compatibility
|
|
7
|
-
module(AZURE_SECURITYGROUP_SECURITYGROUP_TRANSFORMER, []).factory('azureSecurityGroupTransformer', function () {
|
|
8
|
-
function normalizeSecurityGroup() {}
|
|
9
|
-
|
|
10
|
-
return {
|
|
11
|
-
normalizeSecurityGroup: normalizeSecurityGroup,
|
|
12
|
-
};
|
|
13
|
-
});
|
|
1
|
+
export class AzureSecurityGroupTransformer {
|
|
2
|
+
normalizeSecurityGroup() {}
|
|
3
|
+
}
|