Skip to content

Commit

Permalink
GCLOUD2-11786 some updates in image data-source
Browse files Browse the repository at this point in the history
fetch image by image_id options added
  • Loading branch information
alexk53 committed Sep 11, 2024
1 parent 570c987 commit 33350dc
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 38 deletions.
8 changes: 3 additions & 5 deletions docs/data-sources/image.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,13 @@ output "view" {
<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `name` (String) use 'os-version', for example 'ubuntu-20.04'

### Optional

- `is_baremetal` (Boolean) set to true if need to get baremetal image
- `image_id` (String) use 'image_id' if you know it, for example 'f4b1b1b1-1b1b-1b1b-1b1b-1b1b1b1b1b1b'
- `is_baremetal` (Boolean) set to true if you need to get baremetal image
- `metadata_k` (String)
- `metadata_kv` (Map of String)
- `name` (String) use 'os-version', for example 'ubuntu-20.04'
- `project_id` (Number)
- `project_name` (String)
- `region_id` (Number)
Expand Down
105 changes: 72 additions & 33 deletions gcore/data_source_gcore_image.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package gcore

import (
"context"
"fmt"
"log"
"strings"

gcorecloud "github.com/G-Core/gcorelabscloud-go"
"github.com/G-Core/gcorelabscloud-go/gcore/image/v1/images"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
Expand Down Expand Up @@ -57,13 +59,20 @@ func dataSourceImage() *schema.Resource {
},
},
"name": &schema.Schema{
Type: schema.TypeString,
Description: "use 'os-version', for example 'ubuntu-20.04'",
Required: true,
Type: schema.TypeString,
Description: "use 'os-version', for example 'ubuntu-20.04'",
Optional: true,
ExactlyOneOf: []string{"name", "image_id"},
},
"image_id": &schema.Schema{
Type: schema.TypeString,
Description: "use 'image_id' if you know it, for example 'f4b1b1b1-1b1b-1b1b-1b1b-1b1b1b1b1b1b'",
Optional: true,
ExactlyOneOf: []string{"name", "image_id"},
},
"is_baremetal": &schema.Schema{
Type: schema.TypeBool,
Description: "set to true if need to get baremetal image",
Description: "set to true if you need to get baremetal image",
Optional: true,
},
"min_disk": &schema.Schema{
Expand Down Expand Up @@ -124,6 +133,7 @@ func dataSourceImage() *schema.Resource {
func dataSourceImageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Println("[DEBUG] Start Image reading")
name := d.Get("name").(string)
imageID := d.Get("image_id").(string)

config := m.(*Config)
provider := config.Provider
Expand All @@ -137,39 +147,19 @@ func dataSourceImageRead(ctx context.Context, d *schema.ResourceData, m interfac
return diag.FromErr(err)
}

listOpts := &images.ListOpts{}

if metadataK, ok := d.GetOk("metadata_k"); ok {
listOpts.MetadataK = metadataK.(string)
}

if metadataRaw, ok := d.GetOk("metadata_kv"); ok {
typedMetadataKV := make(map[string]string, len(metadataRaw.(map[string]interface{})))
for k, v := range metadataRaw.(map[string]interface{}) {
typedMetadataKV[k] = v.(string)
var image *images.Image
if imageID != "" {
image, err = images.Get(client, imageID).Extract()
if err != nil {
return diag.FromErr(err)
}
listOpts.MetadataKV = typedMetadataKV
}

allImages, err := images.ListAll(client, *listOpts)
if err != nil {
return diag.FromErr(err)
}

var found bool
var image images.Image
for _, img := range allImages {
if strings.HasPrefix(strings.ToLower(img.Name), strings.ToLower(name)) {
image = img
found = true
break
} else {
image, err = findImageByName(client, d, name)
if err != nil {
return diag.FromErr(err)
}
}

if !found {
return diag.Errorf("image with name %s not found", name)
}

d.SetId(image.ID)
d.Set("project_id", d.Get("project_id").(int))
d.Set("region_id", d.Get("region_id").(int))
Expand All @@ -196,3 +186,52 @@ func dataSourceImageRead(ctx context.Context, d *schema.ResourceData, m interfac
log.Println("[DEBUG] Finish Image reading")
return nil
}

func imagesNames(images []images.Image) []string {
result := make([]string, 0, len(images))
for _, img := range images {
result = append(result, fmt.Sprintf("%s (%s)", img.Name, img.ID))
}
return result

}

func findImageByName(client *gcorecloud.ServiceClient, d *schema.ResourceData, name string) (*images.Image, error) {
listOpts := &images.ListOpts{}
if metadataK, ok := d.GetOk("metadata_k"); ok {
listOpts.MetadataK = metadataK.(string)
}

if metadataRaw, ok := d.GetOk("metadata_kv"); ok {
typedMetadataKV := make(map[string]string, len(metadataRaw.(map[string]interface{})))
for k, v := range metadataRaw.(map[string]interface{}) {
typedMetadataKV[k] = v.(string)
}
listOpts.MetadataKV = typedMetadataKV
}

allImages, err := images.ListAll(client, *listOpts)
if err != nil {
return nil, err
}

collectedImages := make([]images.Image, 0)
for _, img := range allImages {
if strings.HasPrefix(strings.ToLower(img.Name), strings.ToLower(name)) {
collectedImages = append(collectedImages, img)
}
}

if len(collectedImages) == 0 {
return nil, fmt.Errorf("image with name %s not found", name)
}

if len(collectedImages) > 1 {
return nil, fmt.Errorf(
"found more than one image with name %s - %s, pls choose image by iamge_id",
name, strings.Join(imagesNames(collectedImages), ", "),
)
}

return &collectedImages[0], nil
}

0 comments on commit 33350dc

Please sign in to comment.