@@ -566,43 +566,15 @@ export class ContainerDefinition extends Construct {
566
566
*/
567
567
public addPortMappings ( ...portMappings : PortMapping [ ] ) {
568
568
this . portMappings . push ( ...portMappings . map ( pm => {
569
- if ( this . taskDefinition . networkMode === NetworkMode . AWS_VPC || this . taskDefinition . networkMode === NetworkMode . HOST ) {
570
- if ( pm . containerPort !== pm . hostPort && pm . hostPort !== undefined ) {
571
- throw new Error ( `Host port (${ pm . hostPort } ) must be left out or equal to container port ${ pm . containerPort } for network mode ${ this . taskDefinition . networkMode } ` ) ;
572
- }
573
- }
574
- // No empty strings as port mapping names.
575
- if ( pm . name === '' ) {
576
- throw new Error ( 'Port mapping name cannot be an empty string.' ) ;
577
- }
578
- // Service connect logic.
579
- if ( pm . name || pm . appProtocol ) {
580
-
581
- // Service connect only supports Awsvpc and Bridge network modes.
582
- if ( ! [ NetworkMode . BRIDGE , NetworkMode . AWS_VPC ] . includes ( this . taskDefinition . networkMode ) ) {
583
- throw new Error ( `Service connect related port mapping fields 'name' and 'appProtocol' are not supported for network mode ${ this . taskDefinition . networkMode } ` ) ;
584
- }
585
-
586
- // Name is not set but App Protocol is; this config is meaningless and we should throw.
587
- if ( ! pm . name ) {
588
- throw new Error ( 'Service connect-related port mapping field \'appProtocol\' cannot be set without \'name\'' ) ;
589
- }
590
-
591
- if ( this . _namedPorts . has ( pm . name ) ) {
592
- throw new Error ( `Port mapping name '${ pm . name } ' already exists on this container` ) ;
593
- }
594
- this . _namedPorts . set ( pm . name , pm ) ;
569
+ const portMap = new PortMap ( this . taskDefinition . networkMode , pm ) ;
570
+ portMap . validate ( ) ;
571
+ const serviceConnect = new ServiceConnect ( this . taskDefinition . networkMode , pm ) ;
572
+ if ( serviceConnect . isServiceConnect ( ) ) {
573
+ serviceConnect . validate ( ) ;
574
+ this . setNamedPort ( pm ) ;
595
575
}
596
-
597
- if ( this . taskDefinition . networkMode === NetworkMode . BRIDGE ) {
598
- if ( pm . hostPort === undefined ) {
599
- pm = {
600
- ...pm ,
601
- hostPort : 0 ,
602
- } ;
603
- }
604
- }
605
- return pm ;
576
+ const sanitizedPM = this . addHostPortIfNeeded ( pm ) ;
577
+ return sanitizedPM ;
606
578
} ) ) ;
607
579
}
608
580
@@ -688,6 +660,32 @@ export class ContainerDefinition extends Construct {
688
660
return this . _namedPorts . get ( name ) ;
689
661
}
690
662
663
+ /**
664
+ * This method adds an namedPort
665
+ */
666
+ private setNamedPort ( pm : PortMapping ) :void {
667
+ if ( ! pm . name ) return ;
668
+ if ( this . _namedPorts . has ( pm . name ) ) {
669
+ throw new Error ( `Port mapping name '${ pm . name } ' already exists on this container` ) ;
670
+ }
671
+ this . _namedPorts . set ( pm . name , pm ) ;
672
+ }
673
+
674
+
675
+ /**
676
+ * Set HostPort to 0 When netowork mode is Brdige
677
+ */
678
+ private addHostPortIfNeeded ( pm : PortMapping ) :PortMapping {
679
+ const newPM = {
680
+ ...pm ,
681
+ } ;
682
+ if ( this . taskDefinition . networkMode !== NetworkMode . BRIDGE ) return newPM ;
683
+ if ( pm . hostPort !== undefined ) return newPM ;
684
+ newPM . hostPort = 0 ;
685
+ return newPM ;
686
+ }
687
+
688
+
691
689
/**
692
690
* Whether this container definition references a specific JSON field of a secret
693
691
* stored in Secrets Manager.
@@ -1086,6 +1084,116 @@ export interface PortMapping {
1086
1084
readonly appProtocol ?: AppProtocol ;
1087
1085
}
1088
1086
1087
+ /**
1088
+ * PortMap ValueObjectClass having by ContainerDefinition
1089
+ */
1090
+ export class PortMap {
1091
+
1092
+ /**
1093
+ * The networking mode to use for the containers in the task.
1094
+ */
1095
+ readonly networkmode : NetworkMode ;
1096
+
1097
+ /**
1098
+ * Port mappings allow containers to access ports on the host container instance to send or receive traffic.
1099
+ */
1100
+ readonly portmapping : PortMapping ;
1101
+
1102
+ constructor ( networkmode : NetworkMode , pm : PortMapping ) {
1103
+ this . networkmode = networkmode ;
1104
+ this . portmapping = pm ;
1105
+ }
1106
+
1107
+ /**
1108
+ * validate invalid portmapping and networkmode parameters.
1109
+ * throw Error when invalid parameters.
1110
+ */
1111
+ public validate ( ) : void {
1112
+ if ( ! this . isvalidPortName ( ) ) {
1113
+ throw new Error ( 'Port mapping name cannot be an empty string.' ) ;
1114
+ }
1115
+ if ( ! this . isValidPorts ( ) ) {
1116
+ const pm = this . portmapping ;
1117
+ throw new Error ( `Host port (${ pm . hostPort } ) must be left out or equal to container port ${ pm . containerPort } for network mode ${ this . networkmode } ` ) ;
1118
+ }
1119
+ }
1120
+
1121
+ private isvalidPortName ( ) : boolean {
1122
+ if ( this . portmapping . name === '' ) {
1123
+ return false ;
1124
+ }
1125
+ return true ;
1126
+ }
1127
+
1128
+ private isValidPorts ( ) :boolean {
1129
+ const isAwsVpcMode = this . networkmode == NetworkMode . AWS_VPC ;
1130
+ const isHostMode = this . networkmode == NetworkMode . HOST ;
1131
+ if ( ! isAwsVpcMode && ! isHostMode ) return true ;
1132
+ const hostPort = this . portmapping . hostPort ;
1133
+ const containerPort = this . portmapping . containerPort ;
1134
+ if ( containerPort !== hostPort && hostPort !== undefined ) return false ;
1135
+ return true ;
1136
+ }
1137
+
1138
+ }
1139
+
1140
+
1141
+ /**
1142
+ * ServiceConnect ValueObjectClass having by ContainerDefinition
1143
+ */
1144
+ export class ServiceConnect {
1145
+ /**
1146
+ * Port mappings allow containers to access ports on the host container instance to send or receive traffic.
1147
+ */
1148
+ readonly portmapping : PortMapping ;
1149
+
1150
+ /**
1151
+ * The networking mode to use for the containers in the task.
1152
+ */
1153
+ readonly networkmode : NetworkMode ;
1154
+
1155
+ constructor ( networkmode : NetworkMode , pm : PortMapping ) {
1156
+ this . portmapping = pm ;
1157
+ this . networkmode = networkmode ;
1158
+ }
1159
+
1160
+ /**
1161
+ * Judge parameters can be serviceconnect logick.
1162
+ * If parameters can be serviceConnect return true.
1163
+ */
1164
+ public isServiceConnect ( ) :boolean {
1165
+ const hasPortname = this . portmapping . name ;
1166
+ const hasAppProtcol = this . portmapping . appProtocol ;
1167
+ if ( hasPortname || hasAppProtcol ) return true ;
1168
+ return false ;
1169
+ }
1170
+
1171
+ /**
1172
+ * Judge serviceconnect parametes are valid.
1173
+ * If invalid, throw Error.
1174
+ */
1175
+ public validate ( ) :void {
1176
+ if ( ! this . isValidNetworkmode ( ) ) {
1177
+ throw new Error ( `Service connect related port mapping fields 'name' and 'appProtocol' are not supported for network mode ${ this . networkmode } ` ) ;
1178
+ }
1179
+ if ( ! this . isValidPortName ( ) ) {
1180
+ throw new Error ( 'Service connect-related port mapping field \'appProtocol\' cannot be set without \'name\'' ) ;
1181
+ }
1182
+ }
1183
+
1184
+ private isValidNetworkmode ( ) :boolean {
1185
+ const isAwsVpcMode = this . networkmode == NetworkMode . AWS_VPC ;
1186
+ const isBridgeMode = this . networkmode == NetworkMode . BRIDGE ;
1187
+ if ( isAwsVpcMode || isBridgeMode ) return true ;
1188
+ return false ;
1189
+ }
1190
+
1191
+ private isValidPortName ( ) :boolean {
1192
+ if ( ! this . portmapping . name ) return false ;
1193
+ return true ;
1194
+ }
1195
+ }
1196
+
1089
1197
/**
1090
1198
* Network protocol
1091
1199
*/
0 commit comments