@@ -931,6 +931,223 @@ describe('LKE Cluster Creation with ACL', () => {
931931 . should ( 'be.enabled' ) ;
932932 } ) ;
933933
934+ /**
935+ * - Confirms create flow for LKE-E cluster with ACL enabled by default
936+ * - Confirms at least one IP must be provided for ACL unless acknowledgement is checked
937+ * - Confirms the cluster details page shows ACL is enabled
938+ */
939+ it ( 'creates an LKE cluster with ACL enabled by default and handles IP address validation' , ( ) => {
940+ const clusterLabel = randomLabel ( ) ;
941+ const mockedEnterpriseCluster = kubernetesClusterFactory . build ( {
942+ k8s_version : latestEnterpriseTierKubernetesVersion . id ,
943+ label : clusterLabel ,
944+ region : 'us-iad' ,
945+ tier : 'enterprise' ,
946+ } ) ;
947+ const mockedEnterpriseClusterPools = [ nanodeMemoryPool ] ;
948+ const mockACL = kubernetesControlPlaneACLFactory . build ( {
949+ acl : {
950+ addresses : {
951+ ipv4 : [ ] ,
952+ ipv6 : [ ] ,
953+ } ,
954+ enabled : true ,
955+ 'revision-id' : '' ,
956+ } ,
957+ } ) ;
958+ mockGetControlPlaneACL ( mockedEnterpriseCluster . id , mockACL ) . as (
959+ 'getControlPlaneACL'
960+ ) ;
961+ mockGetAccount (
962+ accountFactory . build ( {
963+ capabilities : [
964+ 'Kubernetes Enterprise' ,
965+ 'LKE HA Control Planes' ,
966+ 'LKE Network Access Control List (IP ACL)' ,
967+ ] ,
968+ } )
969+ ) . as ( 'getAccount' ) ;
970+ mockGetTieredKubernetesVersions ( 'enterprise' , [
971+ latestEnterpriseTierKubernetesVersion ,
972+ ] ) . as ( 'getTieredKubernetesVersions' ) ;
973+ mockGetKubernetesVersions ( [ latestKubernetesVersion ] ) . as (
974+ 'getKubernetesVersions'
975+ ) ;
976+ mockGetLinodeTypes ( mockedLKEClusterTypes ) . as ( 'getLinodeTypes' ) ;
977+ mockGetLKEClusterTypes ( mockedLKEEnterprisePrices ) . as (
978+ 'getLKEEnterpriseClusterTypes'
979+ ) ;
980+ mockGetRegions ( [
981+ regionFactory . build ( {
982+ capabilities : [ 'Linodes' , 'Kubernetes' , 'Kubernetes Enterprise' ] ,
983+ id : 'us-iad' ,
984+ label : 'Washington, DC' ,
985+ } ) ,
986+ ] ) . as ( 'getRegions' ) ;
987+ mockGetCluster ( mockedEnterpriseCluster ) . as ( 'getCluster' ) ;
988+ mockCreateCluster ( mockedEnterpriseCluster ) . as ( 'createCluster' ) ;
989+ mockGetClusters ( [ mockedEnterpriseCluster ] ) . as ( 'getClusters' ) ;
990+ mockGetClusterPools (
991+ mockedEnterpriseCluster . id ,
992+ mockedEnterpriseClusterPools
993+ ) . as ( 'getClusterPools' ) ;
994+ mockGetDashboardUrl ( mockedEnterpriseCluster . id ) . as ( 'getDashboardUrl' ) ;
995+ mockGetApiEndpoints ( mockedEnterpriseCluster . id ) . as ( 'getApiEndpoints' ) ;
996+
997+ cy . visitWithLogin ( '/kubernetes/clusters' ) ;
998+ cy . wait ( [ '@getAccount' ] ) ;
999+
1000+ ui . button
1001+ . findByTitle ( 'Create Cluster' )
1002+ . should ( 'be.visible' )
1003+ . should ( 'be.enabled' )
1004+ . click ( ) ;
1005+
1006+ cy . url ( ) . should ( 'endWith' , '/kubernetes/create' ) ;
1007+ cy . wait ( [ '@getKubernetesVersions' , '@getTieredKubernetesVersions' ] ) ;
1008+
1009+ // Select enterprise tier.
1010+ cy . get ( `[data-qa-select-card-heading="LKE Enterprise"]` )
1011+ . closest ( '[data-qa-selection-card]' )
1012+ . click ( ) ;
1013+
1014+ cy . wait ( [ '@getLKEEnterpriseClusterTypes' , '@getRegions' ] ) ;
1015+
1016+ // Select a supported region.
1017+ ui . regionSelect . find ( ) . clear ( ) . type ( 'Washington, DC{enter}' ) ;
1018+
1019+ // Select an enterprise version.
1020+ ui . autocomplete
1021+ . findByLabel ( 'Kubernetes Version' )
1022+ . should ( 'be.visible' )
1023+ . click ( ) ;
1024+
1025+ clusterPlans . forEach ( ( clusterPlan ) => {
1026+ const nodeCount = clusterPlan . nodeCount ;
1027+ const planName = clusterPlan . planName ;
1028+ // Click the right tab for the plan, and add a node pool with the desired
1029+ // number of nodes.
1030+ cy . findByText ( clusterPlan . tab ) . should ( 'be.visible' ) . click ( ) ;
1031+ const quantityInput = '[name="Quantity"]' ;
1032+ cy . findByText ( planName )
1033+ . should ( 'be.visible' )
1034+ . closest ( 'tr' )
1035+ . within ( ( ) => {
1036+ cy . get ( quantityInput ) . should ( 'be.visible' ) ;
1037+ cy . get ( quantityInput ) . click ( ) ;
1038+ cy . get ( quantityInput ) . type ( `{selectall}${ nodeCount } ` ) ;
1039+
1040+ ui . button
1041+ . findByTitle ( 'Add' )
1042+ . should ( 'be.visible' )
1043+ . should ( 'be.enabled' )
1044+ . click ( ) ;
1045+ } ) ;
1046+ } ) ;
1047+
1048+ // Confirm ACL is enabled by default.
1049+ cy . contains ( 'Control Plane ACL' ) . should ( 'be.visible' ) ;
1050+ ui . toggle
1051+ . find ( )
1052+ . should ( 'have.attr' , 'data-qa-toggle' , 'true' )
1053+ . should ( 'be.visible' ) ;
1054+ cy . findByRole ( 'checkbox' , { name : / P r o v i d e a n A C L l a t e r / } ) . should (
1055+ 'not.be.checked'
1056+ ) ;
1057+
1058+ // Try to submit the form without the ACL acknowledgement checked.
1059+ cy . get ( '[data-testid="kube-checkout-bar"]' )
1060+ . should ( 'be.visible' )
1061+ . within ( ( ) => {
1062+ ui . button
1063+ . findByTitle ( 'Create Cluster' )
1064+ . should ( 'be.visible' )
1065+ . should ( 'be.enabled' )
1066+ . click ( ) ;
1067+ } ) ;
1068+
1069+ // Confirm error validation requires an ACL IP.
1070+ cy . findByText (
1071+ 'At least one IP address or CIDR range is required for LKE Enterprise.'
1072+ ) . should ( 'be.visible' ) ;
1073+
1074+ // Add an IP,
1075+ cy . findByLabelText ( 'IPv4 Addresses or CIDRs ip-address-0' )
1076+ . should ( 'be.visible' )
1077+ . click ( ) ;
1078+ cy . focused ( ) . clear ( ) ;
1079+ cy . focused ( ) . type ( '10.0.0.0/24' ) ;
1080+
1081+ cy . get ( '[data-testid="kube-checkout-bar"]' )
1082+ . should ( 'be.visible' )
1083+ . within ( ( ) => {
1084+ // Try to submit the form again.
1085+ ui . button
1086+ . findByTitle ( 'Create Cluster' )
1087+ . should ( 'be.visible' )
1088+ . should ( 'be.enabled' )
1089+ . click ( ) ;
1090+ } ) ;
1091+
1092+ // Confirm the validation message is gone.
1093+ cy . findByText (
1094+ 'At least one IP address or CIDR range is required for LKE Enterprise.'
1095+ ) . should ( 'not.exist' ) ;
1096+
1097+ // Check the acknowledgement to prevent IP validation.
1098+ cy . findByRole ( 'checkbox' , { name : / P r o v i d e a n A C L l a t e r / } ) . check ( ) ;
1099+
1100+ // Clear the IP address field and check the acknowledgement to confirm the form can now submit without IP address validation.
1101+ cy . findByLabelText ( 'IPv4 Addresses or CIDRs ip-address-0' )
1102+ . should ( 'be.visible' )
1103+ . click ( ) ;
1104+ cy . focused ( ) . clear ( ) ;
1105+ cy . findByRole ( 'checkbox' , { name : / P r o v i d e a n A C L l a t e r / } ) . check ( ) ;
1106+
1107+ // Finally, add a label, so the form will submit.
1108+ cy . findByLabelText ( 'Cluster Label' ) . should ( 'be.visible' ) . click ( ) ;
1109+ cy . focused ( ) . type ( `${ clusterLabel } {enter}` ) ;
1110+
1111+ cy . get ( '[data-testid="kube-checkout-bar"]' )
1112+ . should ( 'be.visible' )
1113+ . within ( ( ) => {
1114+ // Try to submit the form.
1115+ ui . button
1116+ . findByTitle ( 'Create Cluster' )
1117+ . should ( 'be.visible' )
1118+ . should ( 'be.enabled' )
1119+ . click ( ) ;
1120+ } ) ;
1121+
1122+ // Confirm the validation message is gone.
1123+ cy . findByText (
1124+ 'At least one IP address or CIDR range is required for LKE Enterprise.'
1125+ ) . should ( 'not.exist' ) ;
1126+
1127+ cy . wait ( [
1128+ '@getCluster' ,
1129+ '@getClusterPools' ,
1130+ '@createCluster' ,
1131+ '@getLKEEnterpriseClusterTypes' ,
1132+ '@getLinodeTypes' ,
1133+ '@getDashboardUrl' ,
1134+ '@getApiEndpoints' ,
1135+ '@getControlPlaneACL' ,
1136+ ] ) ;
1137+
1138+ cy . url ( ) . should (
1139+ 'endWith' ,
1140+ `/kubernetes/clusters/${ mockedEnterpriseCluster . id } /summary`
1141+ ) ;
1142+
1143+ // Confirms Summary panel displays as expected
1144+ cy . contains ( 'Control Plane ACL' ) . should ( 'be.visible' ) ;
1145+ ui . button
1146+ . findByTitle ( 'Enabled (0 IP Addresses)' )
1147+ . should ( 'be.visible' )
1148+ . should ( 'be.enabled' ) ;
1149+ } ) ;
1150+
9341151 /**
9351152 * - Confirms IP validation error appears when a bad IP is entered
9361153 * - Confirms IP validation error disappears when a valid IP is entered
@@ -1089,7 +1306,7 @@ describe('LKE Cluster Creation with LKE-E', () => {
10891306 * - Confirms an LKE-E supported region can be selected
10901307 * - Confirms an LKE-E supported k8 version can be selected
10911308 * - Confirms the APL section is disabled while it remains unsupported
1092- * - Confirms at least one IP must be provided for ACL
1309+ * - Confirms ACL is enabled by default
10931310 * - Confirms the checkout bar displays the correct LKE-E info
10941311 * - Confirms an enterprise cluster can be created with the correct chip, version, and price
10951312 * - Confirms that the total node count for each pool is displayed
@@ -1103,7 +1320,20 @@ describe('LKE Cluster Creation with LKE-E', () => {
11031320 tier : 'enterprise' ,
11041321 } ) ;
11051322 const mockedEnterpriseClusterPools = [ nanodeMemoryPool , dedicatedCpuPool ] ;
1323+ const mockACL = kubernetesControlPlaneACLFactory . build ( {
1324+ acl : {
1325+ addresses : {
1326+ ipv4 : [ '10.0.0.0/24' ] ,
1327+ ipv6 : [ ] ,
1328+ } ,
1329+ enabled : true ,
1330+ 'revision-id' : '' ,
1331+ } ,
1332+ } ) ;
11061333
1334+ mockGetControlPlaneACL ( mockedEnterpriseCluster . id , mockACL ) . as (
1335+ 'getControlPlaneACL'
1336+ ) ;
11071337 mockGetAccountBeta (
11081338 accountBetaFactory . build ( {
11091339 id : 'apl' ,
@@ -1287,19 +1517,14 @@ describe('LKE Cluster Creation with LKE-E', () => {
12871517 cy . findByText ( 'Linode 2 GB Plan' ) . should ( 'be.visible' ) ;
12881518 cy . findByText ( '$15.00' ) . should ( 'be.visible' ) ;
12891519 cy . findByText ( '$459.00' ) . should ( 'be.visible' ) ;
1290-
1291- // Try to submit the form
1292- ui . button
1293- . findByTitle ( 'Create Cluster' )
1294- . should ( 'be.visible' )
1295- . should ( 'be.enabled' )
1296- . click ( ) ;
12971520 } ) ;
12981521
1299- // Confirm error validation requires an ACL IP
1300- cy . findByText (
1301- 'At least one IP address or CIDR range is required for LKE Enterprise.'
1302- ) . should ( 'be.visible' ) ;
1522+ // Confirms ACL is enabled by default.
1523+ cy . contains ( 'Control Plane ACL' ) . should ( 'be.visible' ) ;
1524+ ui . toggle
1525+ . find ( )
1526+ . should ( 'have.attr' , 'data-qa-toggle' , 'true' )
1527+ . should ( 'be.visible' ) ;
13031528
13041529 // Add an IP
13051530 cy . findByLabelText ( 'IPv4 Addresses or CIDRs ip-address-0' )
@@ -1319,10 +1544,6 @@ describe('LKE Cluster Creation with LKE-E', () => {
13191544 . click ( ) ;
13201545 } ) ;
13211546
1322- cy . findByText (
1323- 'At least one IP address or CIDR range is required for LKE Enterprise.'
1324- ) . should ( 'not.exist' ) ;
1325-
13261547 // Wait for LKE cluster to be created and confirm that we are redirected
13271548 // to the cluster summary page.
13281549 cy . wait ( [
@@ -1333,6 +1554,7 @@ describe('LKE Cluster Creation with LKE-E', () => {
13331554 '@getLinodeTypes' ,
13341555 '@getDashboardUrl' ,
13351556 '@getApiEndpoints' ,
1557+ '@getControlPlaneACL' ,
13361558 ] ) ;
13371559
13381560 cy . url ( ) . should (
0 commit comments