@@ -213,6 +213,15 @@ data "tencentcloud_vpc_subnets" "vpc_first" {
213213 availability_zone = var.availability_zone_first
214214}
215215
216+ # fetch latest addon(chart) versions
217+ data "tencentcloud_kubernetes_charts" "charts" {}
218+
219+ locals {
220+ chartNames = data.tencentcloud_kubernetes_charts.charts.chart_list.*.name
221+ chartVersions = data.tencentcloud_kubernetes_charts.charts.chart_list.*.latest_version
222+ chartMap = zipmap(local.chartNames, local.chartVersions)
223+ }
224+
216225resource "tencentcloud_kubernetes_cluster" "cluster_with_addon" {
217226 vpc_id = data.tencentcloud_vpc_subnets.vpc_first.instance_list.0.vpc_id
218227 cluster_cidr = var.cluster_cidr
@@ -242,28 +251,31 @@ resource "tencentcloud_kubernetes_cluster" "cluster_with_addon" {
242251 }
243252
244253 extension_addon {
245- name = "NodeProblemDetectorPlus"
246- param = "{\"kind\":\"NodeProblemDetector\",\"apiVersion\":\"platform.tke/v1\",\"metadata\":{\"generateName\":\"npd\"},\"spec\":{\"version\":\"v2.0.0\",\"selfCure\":true,\"uin\":\"12345\",\"subUin\":\"12345\",\"policys\":[{\"actions\":{\"CVM\":{\"reBootCVM\":true,\"retryCounts\":1},\"runtime\":{\"reStartDokcer\":true,\"reStartKubelet\":true,\"retryCounts\":1},\"nodePod\":{\"evict\":true,\"retryCounts\":1}},\"conditionType\":\"Ready\"},{\"actions\":{\"runtime\":{\"reStartDokcer\":true,\"reStartKubelet\":true,\"retryCounts\":1}},\"conditionType\":\"KubeletProblem\"},{\"actions\":{\"runtime\":{\"reStartDokcer\":true,\"reStartKubelet\":false,\"retryCounts\":1}},\"conditionType\":\"DockerdProblem\"}]}}"
247- }
248- extension_addon {
249- name = "OOMGuard"
250- param = "{\"kind\":\"OOMGuard\",\"apiVersion\":\"platform.tke/v1\",\"metadata\":{\"generateName\":\"oom\"},\"spec\":{}}"
251- }
252- extension_addon {
253- name = "DNSAutoscaler"
254- param = "{\"kind\":\"DNSAutoscaler\",\"apiVersion\":\"platform.tke/v1\",\"metadata\":{\"generateName\":\"da\"},\"spec\":{}}"
254+ name = "COS"
255+ param = jsonencode({
256+ "kind" : "App", "spec" : {
257+ "chart" : { "chartName" : "cos", "chartVersion" : local.chartMap["cos"] },
258+ "values" : { "values" : [], "rawValues" : "e30=", "rawValuesType" : "json" }
259+ }
260+ })
255261 }
256262 extension_addon {
257- name = "COS"
258- param = "{\"kind\":\"COS\",\"apiVersion\":\"platform.tke/v1\",\"metadata\":{\"generateName\":\"cos\"},\"spec\":{\"version\":\"1.0.0\"}}"
263+ name = "SecurityGroupPolicy"
264+ param = jsonencode({
265+ "kind" : "App", "spec" : { "chart" : { "chartName" : "securitygrouppolicy", "chartVersion" : local.chartMap["securitygrouppolicy"] } }
266+ })
259267 }
260268 extension_addon {
261- name = "CFS"
262- param = "{\"kind\":\"CFS\",\"apiVersion\":\"platform.tke/v1\",\"metadata\":{\"generateName\":\"cfs\"},\"spec\":{\"version\":\"1.0.0\"}}"
269+ name = "OOMGuard"
270+ param = jsonencode({
271+ "kind" : "App", "spec" : { "chart" : { "chartName" : "oomguard", "chartVersion" : local.chartMap["oomguard"] } }
272+ })
263273 }
264274 extension_addon {
265- name = "CBS"
266- param = "{\"kind\":\"CBS\",\"apiVersion\":\"platform.tke/v1\",\"metadata\":{\"generateName\":\"cbs\"},\"spec\":{}}"
275+ name = "OLM"
276+ param = jsonencode({
277+ "kind" : "App", "spec" : { "chart" : { "chartName" : "olm", "chartVersion" : local.chartMap["olm"] } }
278+ })
267279 }
268280}
269281```
@@ -1260,9 +1272,9 @@ func resourceTencentCloudTkeCluster() *schema.Resource {
12601272 Description : "Specify cluster authentication configuration. Only available for managed cluster and `cluster_version` >= 1.20." ,
12611273 },
12621274 "extension_addon" : {
1263- Type : schema .TypeList ,
1264- Optional : true ,
1265- ForceNew : true ,
1275+ Type : schema .TypeList ,
1276+ Optional : true ,
1277+ Description : "Information of the add-on to be installed." ,
12661278 Elem : & schema.Resource {
12671279 Schema : map [string ]* schema.Schema {
12681280 "name" : {
@@ -1271,13 +1283,13 @@ func resourceTencentCloudTkeCluster() *schema.Resource {
12711283 Description : "Add-on name." ,
12721284 },
12731285 "param" : {
1274- Type : schema .TypeString ,
1275- Required : true ,
1276- Description : "Description of the add-on resource object in JSON string format." ,
1286+ Type : schema .TypeString ,
1287+ Required : true ,
1288+ DiffSuppressFunc : helper .DiffSupressJSON ,
1289+ Description : "Parameter of the add-on resource object in JSON string format, please check the example at the top of page for reference." ,
12771290 },
12781291 },
12791292 },
1280- Description : "Information of the add-on to be installed." ,
12811293 },
12821294 "log_agent" : {
12831295 Type : schema .TypeList ,
@@ -2908,6 +2920,56 @@ func resourceTencentCloudTkeClusterUpdate(d *schema.ResourceData, meta interface
29082920 }
29092921 }
29102922
2923+ if d .HasChange ("extension_addon" ) {
2924+ o , n := d .GetChange ("extension_addon" )
2925+ adds , removes , changes := resourceTkeGetAddonsDiffs (o .([]interface {}), n .([]interface {}))
2926+ updates := append (adds , changes ... )
2927+ for i := range updates {
2928+ var err error
2929+ addon := updates [i ].(map [string ]interface {})
2930+ param := addon ["param" ].(string )
2931+ name , err := tkeService .GetAddonNameFromJson (param )
2932+ if err != nil {
2933+ return err
2934+ }
2935+ _ , has , _ := tkeService .PollingAddonsPhase (ctx , id , name , nil )
2936+ if has {
2937+ err = tkeService .UpdateExtensionAddon (ctx , id , name , param )
2938+ } else {
2939+ err = tkeService .CreateExtensionAddon (ctx , id , param )
2940+ }
2941+ if err != nil {
2942+ return err
2943+ }
2944+ _ , _ , err = tkeService .PollingAddonsPhase (ctx , id , name , nil )
2945+ if err != nil {
2946+ return err
2947+ }
2948+ }
2949+
2950+ for i := range removes {
2951+ addon := removes [i ].(map [string ]interface {})
2952+ param := addon ["param" ].(string )
2953+ name , err := tkeService .GetAddonNameFromJson (param )
2954+ if err != nil {
2955+ return err
2956+ }
2957+ _ , has , _ := tkeService .PollingAddonsPhase (ctx , id , name , nil )
2958+ if ! has {
2959+ continue
2960+ }
2961+ err = tkeService .DeleteExtensionAddon (ctx , id , name )
2962+ if err != nil {
2963+ return err
2964+ }
2965+ _ , has , _ = tkeService .PollingAddonsPhase (ctx , id , name , nil )
2966+ if has {
2967+ return fmt .Errorf ("addon %s still exists" , name )
2968+ }
2969+ }
2970+
2971+ }
2972+
29112973 d .Partial (false )
29122974 if err := resourceTencentCloudTkeClusterRead (d , meta ); err != nil {
29132975 log .Printf ("[WARN]%s resource.kubernetes_cluster.read after update fail , %s" , logId , err .Error ())
@@ -2992,3 +3054,28 @@ func resourceTencentCloudTkeClusterDelete(d *schema.ResourceData, meta interface
29923054 return err
29933055
29943056}
3057+
3058+ func resourceTkeGetAddonsDiffs (o , n []interface {}) (adds , removes , changes []interface {}) {
3059+ indexByName := func (i interface {}) int {
3060+ v := i .(map [string ]interface {})
3061+ return helper .HashString (v ["name" ].(string ))
3062+ }
3063+ indexAll := func (i interface {}) int {
3064+ v := i .(map [string ]interface {})
3065+ name := v ["name" ].(string )
3066+ param := v ["param" ].(string )
3067+ return helper .HashString (fmt .Sprintf ("%s#%s" , name , param ))
3068+ }
3069+
3070+ os := schema .NewSet (indexByName , o )
3071+ ns := schema .NewSet (indexByName , n )
3072+
3073+ adds = ns .Difference (os ).List ()
3074+ removes = os .Difference (ns ).List ()
3075+
3076+ fullIndexedKeeps := schema .NewSet (indexAll , ns .Intersection (os ).List ())
3077+ fullIndexedOlds := schema .NewSet (indexAll , o )
3078+
3079+ changes = fullIndexedKeeps .Difference (fullIndexedOlds ).List ()
3080+ return
3081+ }
0 commit comments