@@ -414,6 +414,82 @@ func resourceTencentCloudTkeCluster() *schema.Resource {
414414 Default : true ,
415415 Description : "Indicates whether ipvs is enabled. Default is true." ,
416416 },
417+ "cluster_as_enabled" : {
418+ Type : schema .TypeBool ,
419+ ForceNew : true ,
420+ Optional : true ,
421+ Default : false ,
422+ Description : "Indicates whether to enable cluster node auto scaler." ,
423+ },
424+ "cluster_extra_args" : {
425+ Type : schema .TypeList ,
426+ ForceNew : true ,
427+ Optional : true ,
428+ MaxItems : 1 ,
429+ Elem : & schema.Resource {
430+ Schema : map [string ]* schema.Schema {
431+ "kube_apiserver" : {
432+ Type : schema .TypeList ,
433+ ForceNew : true ,
434+ Optional : true ,
435+ Elem : & schema.Schema {Type : schema .TypeString },
436+ Description : "The customized parameters for kube-apiserver." ,
437+ },
438+ "kube_controller_manager" : {
439+ Type : schema .TypeList ,
440+ ForceNew : true ,
441+ Optional : true ,
442+ Elem : & schema.Schema {Type : schema .TypeString },
443+ Description : "The customized parameters for kube-controller-manager." ,
444+ },
445+ "kube_scheduler" : {
446+ Type : schema .TypeList ,
447+ ForceNew : true ,
448+ Optional : true ,
449+ Elem : & schema.Schema {Type : schema .TypeString },
450+ Description : "The customized parameters for kube-scheduler." ,
451+ },
452+ },
453+ },
454+ Description : "Customized parameters for master component,such as kube-apiserver, kube-controller-manager, kube-scheduler." ,
455+ },
456+ "node_name_type" : {
457+ Type : schema .TypeString ,
458+ ForceNew : true ,
459+ Optional : true ,
460+ Default : "lan-ip" ,
461+ Description : "Node name type of Cluster, the available values include: 'lan-ip' and 'hostname', Default is 'lan-ip'." ,
462+ ValidateFunc : validateAllowedStringValue (TKE_CLUSTER_NODE_NAME_TYPE ),
463+ },
464+ "network_type" : {
465+ Type : schema .TypeString ,
466+ ForceNew : true ,
467+ Optional : true ,
468+ Default : "GR" ,
469+ ValidateFunc : validateAllowedStringValue (TKE_CLUSTER_NETWORK_TYPE ),
470+ Description : "Cluster network type, GR or VPC-CNI. Default is GR." ,
471+ },
472+ "is_non_static_ip_mode" : {
473+ Type : schema .TypeBool ,
474+ ForceNew : true ,
475+ Optional : true ,
476+ Default : false ,
477+ Description : "Indicates whether static ip mode is enabled. Default is false." ,
478+ },
479+ "deletion_protection" : {
480+ Type : schema .TypeBool ,
481+ Optional : true ,
482+ Default : false ,
483+ Description : "Indicates whether cluster deletion protection is enabled. Default is false." ,
484+ },
485+ "kube_proxy_mode" : {
486+ Type : schema .TypeString ,
487+ Optional : true ,
488+ Default : "" ,
489+ ValidateFunc : validateAllowedStringValue (TKE_CLUSTER_KUBE_PROXY_MODE ),
490+ Description : "Cluster kube-proxy mode, the available values include: 'kube-proxy-bpf'. Default is not set." +
491+ "When set to kube-proxy-bpf, cluster version greater than 1.14 and with TKE-optimized kernel is required." ,
492+ },
417493 "vpc_id" : {
418494 Type : schema .TypeString ,
419495 ForceNew : true ,
@@ -456,10 +532,13 @@ func resourceTencentCloudTkeCluster() *schema.Resource {
456532 "cluster_cidr" : {
457533 Type : schema .TypeString ,
458534 ForceNew : true ,
459- Required : true ,
535+ Optional : true ,
460536 Description : "A network address block of the cluster. Different from vpc cidr and cidr of other clusters within this vpc. Must be in 10./192.168/172.[16-31] segments." ,
461537 ValidateFunc : func (v interface {}, k string ) (ws []string , errors []error ) {
462538 value := v .(string )
539+ if value == "" {
540+ return
541+ }
463542 _ , ipnet , err := net .ParseCIDR (value )
464543 if err != nil {
465544 errors = append (errors , fmt .Errorf ("%q must contain a valid CIDR, got error parsing: %s" , k , err ))
@@ -473,16 +552,16 @@ func resourceTencentCloudTkeCluster() *schema.Resource {
473552 errors = append (errors , fmt .Errorf ("%q must be a network segment" , k ))
474553 return
475554 }
476- if ! strings .HasPrefix (value , "10." ) && ! strings .HasPrefix (value , "192.168." ) && ! strings .HasPrefix (value , "172." ) {
477- errors = append (errors , fmt .Errorf ("%q must in 10. | 192.168. | 172.[16-31]" , k ))
555+ if ! strings .HasPrefix (value , "9." ) && ! strings . HasPrefix ( value , " 10." ) && ! strings .HasPrefix (value , "192.168." ) && ! strings .HasPrefix (value , "172." ) {
556+ errors = append (errors , fmt .Errorf ("%q must in 9. | 10. | 192.168. | 172.[16-31]" , k ))
478557 return
479558 }
480559
481560 if strings .HasPrefix (value , "172." ) {
482561 nextNo := strings .Split (value , "." )[1 ]
483562 no , _ := strconv .ParseInt (nextNo , 10 , 64 )
484563 if no < 16 || no > 31 {
485- errors = append (errors , fmt .Errorf ("%q must in 10. | 192.168. | 172.[16-31]" , k ))
564+ errors = append (errors , fmt .Errorf ("%q must in 9.0 | 10. | 192.168. | 172.[16-31]" , k ))
486565 return
487566 }
488567 }
@@ -530,6 +609,69 @@ func resourceTencentCloudTkeCluster() *schema.Resource {
530609 },
531610 Description : "The maximum number of services in the cluster. Default is 256. Must be a multiple of 16." ,
532611 },
612+ "service_cidr" : {
613+ Type : schema .TypeString ,
614+ ForceNew : true ,
615+ Optional : true ,
616+ Description : "A network address block of the service. Different from vpc cidr and cidr of other clusters within this vpc. Must be in 10./192.168/172.[16-31] segments." ,
617+ ValidateFunc : func (v interface {}, k string ) (ws []string , errors []error ) {
618+ value := v .(string )
619+ if value == "" {
620+ return
621+ }
622+ _ , ipnet , err := net .ParseCIDR (value )
623+ if err != nil {
624+ errors = append (errors , fmt .Errorf ("%q must contain a valid CIDR, got error parsing: %s" , k , err ))
625+ return
626+ }
627+ if ipnet == nil || value != ipnet .String () {
628+ errors = append (errors , fmt .Errorf ("%q must contain a valid network CIDR, expected %q, got %q" , k , ipnet , value ))
629+ return
630+ }
631+ if ! strings .Contains (value , "/" ) {
632+ errors = append (errors , fmt .Errorf ("%q must be a network segment" , k ))
633+ return
634+ }
635+ if ! strings .HasPrefix (value , "9." ) && ! strings .HasPrefix (value , "10." ) && ! strings .HasPrefix (value , "192.168." ) && ! strings .HasPrefix (value , "172." ) {
636+ errors = append (errors , fmt .Errorf ("%q must in 9. | 10. | 192.168. | 172.[16-31]" , k ))
637+ return
638+ }
639+
640+ if strings .HasPrefix (value , "172." ) {
641+ nextNo := strings .Split (value , "." )[1 ]
642+ no , _ := strconv .ParseInt (nextNo , 10 , 64 )
643+ if no < 16 || no > 31 {
644+ errors = append (errors , fmt .Errorf ("%q must in 9. | 10. | 192.168. | 172.[16-31]" , k ))
645+ return
646+ }
647+ }
648+ return
649+ },
650+ },
651+ "eni_subnet_ids" : {
652+ Type : schema .TypeList ,
653+ Optional : true ,
654+ Elem : & schema.Schema {Type : schema .TypeString },
655+ Description : "Subnet Ids for cluster with VPC-CNI network mode." +
656+ " This field can only set when field `network_type` is 'VPC-CNI'." +
657+ " `eni_subnet_ids` can not empty once be set." ,
658+ },
659+ "claim_expired_seconds" : {
660+ Type : schema .TypeInt ,
661+ Optional : true ,
662+ Default : 300 ,
663+ Description : "Claim expired seconds to recycle ENI." +
664+ " This field can only set when field `network_type` is 'VPC-CNI'." +
665+ " `claim_expired_seconds` must greater or equal than 300 and less than 15768000." ,
666+ ValidateFunc : func (v interface {}, k string ) (ws []string , errors []error ) {
667+ value := v .(int )
668+ if value < 300 || value > 15768000 {
669+ errors = append (errors , fmt .Errorf ("%q must greater or equal than 300 and less than 15768000" , k ))
670+ return
671+ }
672+ return
673+ },
674+ },
533675 "master_config" : {
534676 Type : schema .TypeList ,
535677 ForceNew : true ,
@@ -864,27 +1006,75 @@ func resourceTencentCloudTkeClusterCreate(d *schema.ResourceData, meta interface
8641006 basic .ClusterDescription = v .(string )
8651007 }
8661008
867- advanced .ContainerRuntime = d .Get ("container_runtime" ).(string )
8681009 advanced .Ipvs = d .Get ("cluster_ipvs" ).(bool )
869-
1010+ advanced .AsEnabled = d .Get ("cluster_as_enabled" ).(bool )
1011+ advanced .ContainerRuntime = d .Get ("container_runtime" ).(string )
1012+ advanced .NodeNameType = d .Get ("node_name_type" ).(string )
1013+ advanced .NetworkType = d .Get ("network_type" ).(string )
1014+ advanced .IsNonStaticIpMode = d .Get ("is_non_static_ip_mode" ).(bool )
1015+ advanced .DeletionProtection = d .Get ("deletion_protection" ).(bool )
1016+ advanced .KubeProxyMode = d .Get ("kube_proxy_mode" ).(string )
1017+
1018+ if extraArgs , ok := d .GetOk ("cluster_extra_args" ); ok {
1019+ extraArgList := extraArgs .([]interface {})
1020+ for index := range extraArgList {
1021+ extraArg := extraArgList [index ].(map [string ]interface {})
1022+ if apiserverArgs , exist := extraArg ["kube_apiserver" ]; exist {
1023+ args := apiserverArgs .([]interface {})
1024+ for index := range args {
1025+ advanced .ExtraArgs .KubeAPIServer = append (advanced .ExtraArgs .KubeAPIServer , args [index ].(string ))
1026+ }
1027+ }
1028+ if cmArgs , exist := extraArg ["kube_controller_manager" ]; exist {
1029+ args := cmArgs .([]interface {})
1030+ for index := range args {
1031+ advanced .ExtraArgs .KubeControllerManager = append (advanced .ExtraArgs .KubeControllerManager , args [index ].(string ))
1032+ }
1033+ }
1034+ if schedulerArgs , exist := extraArg ["kube_scheduler" ]; exist {
1035+ args := schedulerArgs .([]interface {})
1036+ for index := range args {
1037+ advanced .ExtraArgs .KubeScheduler = append (advanced .ExtraArgs .KubeScheduler , args [index ].(string ))
1038+ }
1039+ }
1040+ }
1041+ }
8701042 cidrSet .ClusterCidr = d .Get ("cluster_cidr" ).(string )
8711043 cidrSet .IgnoreClusterCidrConflict = d .Get ("ignore_cluster_cidr_conflict" ).(bool )
8721044 cidrSet .MaxClusterServiceNum = int64 (d .Get ("cluster_max_service_num" ).(int ))
8731045 cidrSet .MaxNodePodNum = int64 (d .Get ("cluster_max_pod_num" ).(int ))
1046+ cidrSet .ServiceCIDR = d .Get ("service_cidr" ).(string )
1047+ cidrSet .ClaimExpiredSeconds = int64 (d .Get ("claim_expired_seconds" ).(int ))
1048+
1049+ if advanced .NetworkType == TKE_CLUSTER_NETWORK_TYPE_VPC_CNI {
1050+ // VPC-CNI cluster need to set eni subnet and service cidr.
1051+ eniSubnetIdList := d .Get ("eni_subnet_ids" ).([]interface {})
1052+ for index := range eniSubnetIdList {
1053+ subnetId := eniSubnetIdList [index ].(string )
1054+ cidrSet .EniSubnetIds = append (cidrSet .EniSubnetIds , subnetId )
1055+ }
1056+ if cidrSet .ServiceCIDR == "" || len (cidrSet .EniSubnetIds ) == 0 {
1057+ return fmt .Errorf ("`service_cidr` must be set and `eni_subnet_ids` must be set when cluster `network_type` is VPC-CNI." )
1058+ }
1059+ } else {
1060+ // GR cluster
1061+ if cidrSet .ClusterCidr == "" {
1062+ return fmt .Errorf ("`service_cidr` must be set when cluster `network_type` is GR" )
1063+ }
1064+ items := strings .Split (cidrSet .ClusterCidr , "/" )
1065+ if len (items ) != 2 {
1066+ return fmt .Errorf ("`cluster_cidr` must be network segment " )
1067+ }
8741068
875- items := strings .Split (cidrSet .ClusterCidr , "/" )
876- if len (items ) != 2 {
877- return fmt .Errorf ("`cluster_cidr` must be network segment " )
878- }
879-
880- bitNumber , err := strconv .ParseInt (items [1 ], 10 , 64 )
1069+ bitNumber , err := strconv .ParseInt (items [1 ], 10 , 64 )
8811070
882- if err != nil {
883- return fmt .Errorf ("`cluster_cidr` must be network segment " )
884- }
1071+ if err != nil {
1072+ return fmt .Errorf ("`cluster_cidr` must be network segment " )
1073+ }
8851074
886- if math .Pow (2 , float64 (32 - bitNumber )) <= float64 (cidrSet .MaxNodePodNum ) {
887- return fmt .Errorf ("`cluster_cidr` Network segment range is too small, can not cover cluster_max_service_num" )
1075+ if math .Pow (2 , float64 (32 - bitNumber )) <= float64 (cidrSet .MaxNodePodNum ) {
1076+ return fmt .Errorf ("`cluster_cidr` Network segment range is too small, can not cover cluster_max_service_num" )
1077+ }
8881078 }
8891079
8901080 if masters , ok := d .GetOk ("master_config" ); ok {
0 commit comments