Skip to content

Commit a8fa935

Browse files
committed
fix(kube): Support old and new apiserver customization
1 parent 0de74e5 commit a8fa935

File tree

5 files changed

+139
-28
lines changed

5 files changed

+139
-28
lines changed

ovh/resource_cloud_project_kube.go

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,12 @@ func resourceCloudProjectKube() *schema.Resource {
6565
ForceNew: false,
6666
},
6767
kubeClusterCustomizationApiServerKey: {
68-
Type: schema.TypeSet,
69-
Computed: true,
70-
Optional: true,
71-
ForceNew: false,
72-
Set: CustomSchemaSetFunc(),
68+
Type: schema.TypeSet,
69+
Computed: true,
70+
Optional: true,
71+
ForceNew: false,
72+
Set: CustomSchemaSetFunc(),
73+
ConflictsWith: []string{kubeClusterCustomization},
7374
Elem: &schema.Resource{
7475
Schema: map[string]*schema.Schema{
7576
"admissionplugins": {
@@ -101,12 +102,13 @@ func resourceCloudProjectKube() *schema.Resource {
101102
},
102103
},
103104
kubeClusterCustomization: {
104-
Type: schema.TypeSet,
105-
Computed: true,
106-
Optional: true,
107-
ForceNew: false,
108-
Set: CustomSchemaSetFunc(),
109-
Deprecated: fmt.Sprintf("Use %s instead", kubeClusterCustomizationApiServerKey),
105+
Type: schema.TypeSet,
106+
Computed: true,
107+
Optional: true,
108+
ForceNew: false,
109+
Set: CustomSchemaSetFunc(),
110+
ConflictsWith: []string{kubeClusterCustomizationApiServerKey},
111+
Deprecated: fmt.Sprintf("Use %s instead", kubeClusterCustomizationApiServerKey),
110112
Elem: &schema.Resource{
111113
Schema: map[string]*schema.Schema{
112114
"apiserver": {
@@ -460,8 +462,9 @@ func resourceCloudProjectKubeUpdate(d *schema.ResourceData, meta interface{}) er
460462
if d.HasChange(kubeClusterCustomizationApiServerKey) || d.HasChange(kubeClusterCustomizationKubeProxyKey) {
461463
_, apiServerAdmissionPlugins := d.GetChange(kubeClusterCustomizationApiServerKey)
462464
_, kubeProxyCustomization := d.GetChange(kubeClusterCustomizationKubeProxyKey)
465+
_, oldApiServerCustomization := d.GetChange(kubeClusterCustomization)
463466

464-
customization := loadCustomization(apiServerAdmissionPlugins, kubeProxyCustomization)
467+
customization := loadCustomization(oldApiServerCustomization, apiServerAdmissionPlugins, kubeProxyCustomization)
465468

466469
params := &CloudProjectKubeUpdateCustomizationOpts{
467470
APIServer: customization.APIServer,

ovh/resource_cloud_project_kube_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,22 @@ resource "ovh_cloud_project_kube" "cluster" {
164164
}
165165
`
166166

167+
var testAccCloudProjectKubeDeprecatedCustomizationApiServerAdmissionPluginsUpdateConfigEnabledAndDisabled = `
168+
resource "ovh_cloud_project_kube" "cluster" {
169+
service_name = "%s"
170+
name = "%s"
171+
region = "%s"
172+
customization {
173+
apiserver {
174+
admissionplugins {
175+
enabled = ["NodeRestriction"]
176+
disabled = ["AlwaysPullImages"]
177+
}
178+
}
179+
}
180+
}
181+
`
182+
167183
type configData struct {
168184
Region string
169185
Regions string
@@ -227,6 +243,49 @@ func TestAccCloudProjectKubeCustomizationApiServerAdmissionPlugins(t *testing.T)
227243
})
228244
}
229245

246+
// TestAccCloudProjectKubeDeprecatedCustomizationApiServerAdmissionPlugins aims to test that
247+
// values are the same between customization_apiserver.admissionplugins are the same and customization.apiserver.admissionplugins.
248+
// This is deprecated and will be removed in the future.
249+
func TestAccCloudProjectKubeDeprecatedCustomizationApiServerAdmissionPlugins(t *testing.T) {
250+
region := os.Getenv("OVH_CLOUD_PROJECT_KUBE_REGION_TEST")
251+
serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST")
252+
name := acctest.RandomWithPrefix(test_prefix)
253+
254+
createConfig := fmt.Sprintf(
255+
testAccCloudProjectKubeDeprecatedCustomizationApiServerAdmissionPluginsUpdateConfigEnabledAndDisabled,
256+
serviceName,
257+
name,
258+
region,
259+
)
260+
261+
resource.Test(t, resource.TestCase{
262+
PreCheck: func() {
263+
testAccPreCheckCloud(t)
264+
testAccCheckCloudProjectExists(t)
265+
testAccPreCheckKubernetes(t)
266+
},
267+
Providers: testAccProviders,
268+
Steps: []resource.TestStep{
269+
{
270+
Config: createConfig,
271+
Check: resource.ComposeTestCheckFunc(
272+
resource.TestCheckResourceAttr("ovh_cloud_project_kube.cluster", kubeClusterNameKey, name),
273+
resource.TestCheckResourceAttr("ovh_cloud_project_kube.cluster", "region", region),
274+
resource.TestCheckResourceAttr("ovh_cloud_project_kube.cluster", "service_name", serviceName),
275+
276+
// Deprecated configuration
277+
resource.TestCheckResourceAttr("ovh_cloud_project_kube.cluster", "customization.0.apiserver.0.admissionplugins.0.enabled.0", "NodeRestriction"),
278+
resource.TestCheckResourceAttr("ovh_cloud_project_kube.cluster", "customization.0.apiserver.0.admissionplugins.0.disabled.0", "AlwaysPullImages"),
279+
280+
// New configuration
281+
resource.TestCheckResourceAttr("ovh_cloud_project_kube.cluster", "customization_apiserver.0.admissionplugins.0.enabled.0", "NodeRestriction"),
282+
resource.TestCheckResourceAttr("ovh_cloud_project_kube.cluster", "customization_apiserver.0.admissionplugins.0.disabled.0", "AlwaysPullImages"),
283+
),
284+
},
285+
},
286+
})
287+
}
288+
230289
func TestAccCloudProjectKube_kube_proxy_iptables(t *testing.T) {
231290
region := os.Getenv("OVH_CLOUD_PROJECT_KUBE_REGION_TEST")
232291
serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST")

ovh/types_cloud_project_kube.go

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,12 @@ func (opts *CloudProjectKubeCreateOpts) FromResource(d *schema.ResourceData) *Cl
7373
opts.UpdatePolicy = helpers.GetNilStringPointerFromData(d, "update_policy")
7474
opts.PrivateNetworkId = helpers.GetNilStringPointerFromData(d, "private_network_id")
7575
opts.PrivateNetworkConfiguration = loadPrivateNetworkConfiguration(d.Get("private_network_configuration"))
76-
opts.Customization = loadCustomization(d.Get(kubeClusterCustomizationApiServerKey), d.Get(kubeClusterCustomizationKubeProxyKey))
76+
opts.Customization = loadCustomization(d.Get(kubeClusterCustomization), d.Get(kubeClusterCustomizationApiServerKey), d.Get(kubeClusterCustomizationKubeProxyKey))
7777
opts.KubeProxyMode = helpers.GetNilStringPointerFromData(d, kubeClusterProxyModeKey)
7878
return opts
7979
}
8080

81-
func loadCustomization(apiServerAdmissionPlugins interface{}, kubeProxyCustomizationInterface interface{}) *Customization {
81+
func loadCustomization(oldCustomizationInterface, apiServerAdmissionPlugins, kubeProxyCustomizationInterface interface{}) *Customization {
8282
if apiServerAdmissionPlugins == nil && kubeProxyCustomizationInterface == nil {
8383
return nil
8484
}
@@ -121,6 +121,59 @@ func loadCustomization(apiServerAdmissionPlugins interface{}, kubeProxyCustomiza
121121
}
122122
}
123123

124+
// Old apiserver customization.
125+
// Deprecated, should be removed in the future
126+
if oldCustomizationInterface != nil {
127+
oldCustomizationSet := oldCustomizationInterface.(*schema.Set).List()
128+
if len(oldCustomizationSet) > 0 {
129+
oldApiServerCustomization := oldCustomizationSet[0].(map[string]interface{})
130+
oldApiServerCustomizationSet := oldApiServerCustomization["apiserver"].(*schema.Set).List()
131+
132+
if len(oldApiServerCustomizationSet) > 0 {
133+
oldApiServerCustomizationAdmissionPlugins := oldApiServerCustomizationSet[0].(map[string]interface{})
134+
oldApiServerCustomizationAdmissionPluginsSet := oldApiServerCustomizationAdmissionPlugins["admissionplugins"].(*schema.Set).List()
135+
admissionPlugins := oldApiServerCustomizationAdmissionPluginsSet[0].(map[string]interface{})
136+
137+
containsString := func(s []string, e string) bool {
138+
for _, a := range s {
139+
if a == e {
140+
return true
141+
}
142+
}
143+
return false
144+
}
145+
146+
// Enabled admission plugins
147+
{
148+
stringArray := admissionPlugins["enabled"].([]interface{})
149+
for _, s := range stringArray {
150+
if customizationOutput.APIServer.AdmissionPlugins.Enabled == nil {
151+
customizationOutput.APIServer.AdmissionPlugins.Enabled = new([]string)
152+
}
153+
154+
if !containsString(*customizationOutput.APIServer.AdmissionPlugins.Enabled, s.(string)) {
155+
*customizationOutput.APIServer.AdmissionPlugins.Enabled = append(*customizationOutput.APIServer.AdmissionPlugins.Enabled, s.(string))
156+
}
157+
}
158+
}
159+
160+
// Disabled admission plugins
161+
{
162+
stringArray := admissionPlugins["disabled"].([]interface{})
163+
for _, s := range stringArray {
164+
if customizationOutput.APIServer.AdmissionPlugins.Disabled == nil {
165+
customizationOutput.APIServer.AdmissionPlugins.Disabled = new([]string)
166+
}
167+
168+
if !containsString(*customizationOutput.APIServer.AdmissionPlugins.Disabled, s.(string)) {
169+
*customizationOutput.APIServer.AdmissionPlugins.Disabled = append(*customizationOutput.APIServer.AdmissionPlugins.Disabled, s.(string))
170+
}
171+
}
172+
}
173+
}
174+
}
175+
}
176+
124177
// Nested KubeProxy customization
125178
kubeProxySet := kubeProxyCustomizationInterface.(*schema.Set).List()
126179
if len(kubeProxySet) > 0 {

website/docs/d/cloud_project_kube.html.markdown

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,17 @@ The following attributes are exported:
4242
* `region` - The OVHcloud public cloud region ID of the managed kubernetes cluster.
4343
* `version` - Kubernetes version of the managed kubernetes cluster.
4444
* `private_network_id` - OpenStack private network (or vrack) ID to use.
45-
* `control_plane_is_up_to_date` - True if control-plane is up to date.
46-
* `is_up_to_date` - True if all nodes and control-plane are up to date.
45+
* `control_plane_is_up_to_date` - True if control-plane is up-to-date.
46+
* `is_up_to_date` - True if all nodes and control-plane are up-to-date.
4747
* `next_upgrade_versions` - Kubernetes versions available for upgrade.
4848
* `nodes_url` - Cluster nodes URL.
4949
* `status` - Cluster status. Should be normally set to 'READY'.
5050
* `update_policy` - Cluster update policy. Choose between [ALWAYS_UPDATE,MINIMAL_DOWNTIME,NEVER_UPDATE]'.
5151
* `url` - Management URL of your cluster.
5252
* `kube_proxy_mode` - Selected mode for kube-proxy.
53+
* `customization` - **Deprecated** (Optional) Use `customization_apiserver` and `customization_kube_proxy` instead. Kubernetes cluster customization
54+
* `apiserver` - Kubernetes API server customization
55+
* `kube_proxy` - Kubernetes kube-proxy customization
5356
* `customization_apiserver` - Kubernetes API server customization
5457
* `admissionplugins` - Kubernetes API server admission plugins customization
5558
* `enabled` - Array of admission plugins enabled, default is ["NodeRestriction","AlwaysPulImages"] and only these admission plugins can be enabled at this time.

website/docs/r/cloud_project_kube.html.markdown

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -135,19 +135,14 @@ resource "ovh_cloud_project_kube" "mycluster" {
135135

136136
The following arguments are supported:
137137

138-
* `service_name` - (Optional) The id of the public cloud project. If omitted,
139-
the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used.
140-
138+
* `service_name` - (Optional) The id of the public cloud project. If omitted, the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used.
141139
* `name` - (Optional) The name of the kubernetes cluster.
142-
143-
* `region` - a valid OVHcloud public cloud region ID in which the kubernetes
144-
cluster will be available. Ex.: "GRA1". Defaults to all public cloud regions.
145-
Changing this value recreates the resource.
146-
140+
* `region` - a valid OVHcloud public cloud region ID in which the kubernetes cluster will be available. Ex.: "GRA1". Defaults to all public cloud regions. Changing this value recreates the resource.
147141
* `version` - (Optional) kubernetes version to use. Changing this value updates the resource. Defaults to the latest available.
148-
149142
* `kube_proxy_mode` - (Optional) Selected mode for kube-proxy. **Changing this value recreates the resource. This will result in the loss of all data stored in the etcd.** Defaults to `iptables`.
150-
143+
* `customization` - **Deprecated** (Optional) Use `customization_apiserver` and `customization_kube_proxy` instead. Kubernetes cluster customization
144+
* `apiserver` - Kubernetes API server customization
145+
* `kube_proxy` - Kubernetes kube-proxy customization
151146
* `customization_apiserver` - Kubernetes API server customization
152147
* `admissionplugins` - (Optional) Kubernetes API server admission plugins customization
153148
* `enabled` - (Optional) Array of admission plugins enabled, default is ["NodeRestriction","AlwaysPulImages"] and only these admission plugins can be enabled at this time.
@@ -163,7 +158,6 @@ The following arguments are supported:
163158
* `tcp_timeout` - (Optional) Timeout value used for idle IPVS TCP sessions in [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) duration (e.g. `PT60S`). The default value is `PT0S`, which preserves the current timeout value on the system.
164159
* `tcp_fin_timeout` - (Optional) Timeout value used for IPVS TCP sessions after receiving a FIN in RFC3339 duration (e.g. `PT60S`). The default value is `PT0S`, which preserves the current timeout value on the system.
165160
* `udp_timeout` - (Optional) timeout value used for IPVS UDP packets in [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) duration (e.g. `PT60S`). The default value is `PT0S`, which preserves the current timeout value on the system.
166-
167161
* `private_network_id` - (Optional) OpenStack private network (or vrack) ID to use.
168162
Changing this value delete the resource(including ETCD user data). Defaults - not use private network.
169163

@@ -172,7 +166,6 @@ The following arguments are supported:
172166
* `private_network_configuration` - (Optional) The private network configuration
173167
* default_vrack_gateway - If defined, all egress traffic will be routed towards this IP address, which should belong to the private network. Empty string means disabled.
174168
* private_network_routing_as_default - Defines whether routing should default to using the nodes' private interface, instead of their public interface. Default is false.
175-
176169
* `update_policy` - Cluster update policy. Choose between [ALWAYS_UPDATE, MINIMAL_DOWNTIME, NEVER_UPDATE].
177170

178171
## Attributes Reference

0 commit comments

Comments
 (0)