From 8bf26099e0da5db85f1997789cb867aa11db9906 Mon Sep 17 00:00:00 2001 From: Taras Date: Wed, 6 Dec 2023 23:18:05 +0200 Subject: [PATCH] feat(lxc)!: allow to update `features`, add mount type support (#765) * feat(lxc): allow to update features, add mount type support Signed-off-by: tarik02 * updates according to the MR Signed-off-by: tarik02 * update according to the pull request Signed-off-by: tarik02 --------- Signed-off-by: tarik02 --- .../virtual_environment_container.md | 1 + proxmoxtf/resource/container.go | 98 +++++++++++++------ proxmoxtf/resource/validator/container.go | 20 ++++ 3 files changed, 89 insertions(+), 30 deletions(-) create mode 100644 proxmoxtf/resource/validator/container.go diff --git a/docs/resources/virtual_environment_container.md b/docs/resources/virtual_environment_container.md index b6b06a32..5e0d578d 100644 --- a/docs/resources/virtual_environment_container.md +++ b/docs/resources/virtual_environment_container.md @@ -205,6 +205,7 @@ output "ubuntu_container_public_key" { to `false`) - `keyctl` - (Optional) Whether the container supports `keyctl()` system call (defaults to `false`) + - `mount` - (Optional) List of allowed mount types (`cifs` or `nfs`) ## Attribute Reference diff --git a/proxmoxtf/resource/container.go b/proxmoxtf/resource/container.go index 2bce3512..f93e0c54 100644 --- a/proxmoxtf/resource/container.go +++ b/proxmoxtf/resource/container.go @@ -92,6 +92,7 @@ const ( mkResourceVirtualEnvironmentContainerFeaturesNesting = "nesting" mkResourceVirtualEnvironmentContainerFeaturesKeyControl = "keyctl" mkResourceVirtualEnvironmentContainerFeaturesFUSE = "fuse" + mkResourceVirtualEnvironmentContainerFeaturesMountTypes = "mount" mkResourceVirtualEnvironmentContainerInitialization = "initialization" mkResourceVirtualEnvironmentContainerInitializationDNS = "dns" mkResourceVirtualEnvironmentContainerInitializationDNSDomain = "domain" @@ -315,13 +316,13 @@ func Container() *schema.Resource { Type: schema.TypeList, Description: "Features", Optional: true, - ForceNew: true, DefaultFunc: func() (interface{}, error) { return []interface{}{ map[string]interface{}{ mkResourceVirtualEnvironmentContainerFeaturesNesting: dvResourceVirtualEnvironmentContainerFeaturesNesting, mkResourceVirtualEnvironmentContainerFeaturesKeyControl: dvResourceVirtualEnvironmentContainerFeaturesKeyControl, mkResourceVirtualEnvironmentContainerFeaturesFUSE: dvResourceVirtualEnvironmentContainerFeaturesFUSE, + mkResourceVirtualEnvironmentContainerFeaturesMountTypes: []interface{}{}, }, }, nil }, @@ -331,23 +332,29 @@ func Container() *schema.Resource { Type: schema.TypeBool, Description: "Whether the container runs as nested", Optional: true, - ForceNew: true, Default: dvResourceVirtualEnvironmentContainerFeaturesNesting, }, mkResourceVirtualEnvironmentContainerFeaturesKeyControl: { Type: schema.TypeBool, Description: "Whether the container supports `keyctl()` system call", Optional: true, - ForceNew: true, Default: dvResourceVirtualEnvironmentContainerFeaturesKeyControl, }, mkResourceVirtualEnvironmentContainerFeaturesFUSE: { Type: schema.TypeBool, Description: "Whether the container supports FUSE mounts", Optional: true, - ForceNew: true, Default: dvResourceVirtualEnvironmentContainerFeaturesFUSE, }, + mkResourceVirtualEnvironmentContainerFeaturesMountTypes: { + Type: schema.TypeList, + Description: "List of allowed mount types", + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateDiagFunc: validator.MountType(), + }, + }, }, }, MaxItems: 1, @@ -1216,35 +1223,11 @@ func containerCreateCustom(ctx context.Context, d *schema.ResourceData, m interf } } - featuresBlock, err := structure.GetSchemaBlock( - resource, - d, - []string{mkResourceVirtualEnvironmentContainerFeatures}, - 0, - true, - ) + features, err := containerGetFeatures(resource, d) if err != nil { return diag.FromErr(err) } - nesting := types.CustomBool(featuresBlock[mkResourceVirtualEnvironmentContainerFeaturesNesting].(bool)) - keyctl := types.CustomBool(featuresBlock[mkResourceVirtualEnvironmentContainerFeaturesKeyControl].(bool)) - fuse := types.CustomBool(featuresBlock[mkResourceVirtualEnvironmentContainerFeaturesFUSE].(bool)) - - features := containers.CustomFeatures{} - - if nesting { - features.Nesting = &nesting - } - - if keyctl { - features.KeyControl = &keyctl - } - - if fuse { - features.FUSE = &fuse - } - initialization := d.Get(mkResourceVirtualEnvironmentContainerInitialization).([]interface{}) initializationDNSDomain := dvResourceVirtualEnvironmentContainerInitializationDNSDomain initializationDNSServer := dvResourceVirtualEnvironmentContainerInitializationDNSServer @@ -1494,7 +1477,7 @@ func containerCreateCustom(ctx context.Context, d *schema.ResourceData, m interf CPUUnits: &cpuUnits, DatastoreID: &diskDatastoreID, DedicatedMemory: &memoryDedicated, - Features: &features, + Features: features, MountPoints: mountPointArray, NetworkInterfaces: networkInterfaceArray, OSTemplateFileVolume: &operatingSystemTemplateFileID, @@ -1711,6 +1694,52 @@ func containerGetTagsString(d *schema.ResourceData) string { return strings.Join(sanitizedTags, ";") } +func containerGetFeatures(resource *schema.Resource, d *schema.ResourceData) (*containers.CustomFeatures, error) { + featuresBlock, err := structure.GetSchemaBlock( + resource, + d, + []string{mkResourceVirtualEnvironmentContainerFeatures}, + 0, + true, + ) + if err != nil { + return nil, fmt.Errorf("error getting container features from schema: %w", err) + } + + nesting := types.CustomBool(featuresBlock[mkResourceVirtualEnvironmentContainerFeaturesNesting].(bool)) + keyctl := types.CustomBool(featuresBlock[mkResourceVirtualEnvironmentContainerFeaturesKeyControl].(bool)) + fuse := types.CustomBool(featuresBlock[mkResourceVirtualEnvironmentContainerFeaturesFUSE].(bool)) + mountTypes := featuresBlock[mkResourceVirtualEnvironmentContainerFeaturesMountTypes].([]interface{}) + + var mountTypesConverted []string + if mountTypes != nil { + mountTypesConverted = make([]string, len(mountTypes)) + for i, mountType := range mountTypes { + mountTypesConverted[i] = mountType.(string) + } + } else { + mountTypesConverted = []string{} + } + + features := containers.CustomFeatures{ + MountTypes: &mountTypesConverted, + } + + if nesting { + features.Nesting = &nesting + } + + if keyctl { + features.KeyControl = &keyctl + } + + if fuse { + features.FUSE = &fuse + } + + return &features, nil +} + func containerRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var diags diag.Diagnostics @@ -2363,6 +2392,15 @@ func containerUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) rebootRequired = true } + if d.HasChange(mkResourceVirtualEnvironmentContainerFeatures) { + features, err := containerGetFeatures(resource, d) + if err != nil { + return diag.FromErr(err) + } + + updateBody.Features = features + } + // Prepare the new initialization configuration. initialization := d.Get(mkResourceVirtualEnvironmentContainerInitialization).([]interface{}) initializationDNSDomain := dvResourceVirtualEnvironmentContainerInitializationDNSDomain diff --git a/proxmoxtf/resource/validator/container.go b/proxmoxtf/resource/validator/container.go new file mode 100644 index 00000000..963775ea --- /dev/null +++ b/proxmoxtf/resource/validator/container.go @@ -0,0 +1,20 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +package validator + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +// MountType returns a schema validation function for a mount type on a lxc container. +func MountType() schema.SchemaValidateDiagFunc { + return validation.ToDiagFunc(validation.StringInSlice([]string{ + "cifs", + "nfs", + }, false)) +}