-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: support container image datasource (#30)
- Loading branch information
Showing
6 changed files
with
395 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
--- | ||
# generated by https://github.com/hashicorp/terraform-plugin-docs | ||
page_title: "ec_container_image Data Source - terraform-provider-ec" | ||
subcategory: "" | ||
description: |- | ||
Use this data source to access information about an existing Image. | ||
--- | ||
|
||
# ec_container_image (Data Source) | ||
|
||
Use this data source to access information about an existing Image. | ||
|
||
|
||
|
||
<!-- schema generated by tfplugindocs --> | ||
## Schema | ||
|
||
### Optional | ||
|
||
- `instance` (String) Name is an instance name configured in the provider. | ||
- `metadata` (Block List, Max: 1) Image object metadata. (see [below for nested schema](#nestedblock--metadata)) | ||
- `spec` (Block List, Max: 1) Spec defines the desired image. (see [below for nested schema](#nestedblock--spec)) | ||
|
||
### Read-Only | ||
|
||
- `id` (String) The ID of this resource. | ||
|
||
<a id="nestedblock--metadata"></a> | ||
### Nested Schema for `metadata` | ||
|
||
Required: | ||
|
||
- `branch` (String) Branch defines the branch within which each name must be unique. | ||
|
||
Optional: | ||
|
||
- `object_meta` (Block List, Max: 1) (see [below for nested schema](#nestedblock--metadata--object_meta)) | ||
|
||
<a id="nestedblock--metadata--object_meta"></a> | ||
### Nested Schema for `metadata.object_meta` | ||
|
||
Optional: | ||
|
||
- `annotations` (Map of String) An unstructured map of keys and values stored on an object. | ||
- `environment` (String) The name of the environment the object belongs to. | ||
- `labels` (Map of String) A map of keys and values that can be used to organize and categorize objects. | ||
- `name` (String) The unique object name within its scope. | ||
|
||
Read-Only: | ||
|
||
- `revision` (String) An opaque resource revision. | ||
- `uid` (String) A unique identifier for each an object. | ||
|
||
|
||
|
||
<a id="nestedblock--spec"></a> | ||
### Nested Schema for `spec` | ||
|
||
Required: | ||
|
||
- `image` (String) Image is the image name. | ||
|
||
Optional: | ||
|
||
- `tag` (String) Tag is the image tag. | ||
|
||
Read-Only: | ||
|
||
- `digest` (String) Digest is the hash of the image. | ||
- `registry` (String) Registry is the registry that contains the image. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
--- | ||
# generated by https://github.com/hashicorp/terraform-plugin-docs | ||
page_title: "ec_container_image_v1 Data Source - terraform-provider-ec" | ||
subcategory: "" | ||
description: |- | ||
Use this data source to access information about an existing Image. | ||
--- | ||
|
||
# ec_container_image_v1 (Data Source) | ||
|
||
Use this data source to access information about an existing Image. | ||
|
||
|
||
|
||
<!-- schema generated by tfplugindocs --> | ||
## Schema | ||
|
||
### Optional | ||
|
||
- `instance` (String) Name is an instance name configured in the provider. | ||
- `metadata` (Block List, Max: 1) Image object metadata. (see [below for nested schema](#nestedblock--metadata)) | ||
- `spec` (Block List, Max: 1) Spec defines the desired image. (see [below for nested schema](#nestedblock--spec)) | ||
|
||
### Read-Only | ||
|
||
- `id` (String) The ID of this resource. | ||
|
||
<a id="nestedblock--metadata"></a> | ||
### Nested Schema for `metadata` | ||
|
||
Required: | ||
|
||
- `branch` (String) Branch defines the branch within which each name must be unique. | ||
|
||
Optional: | ||
|
||
- `object_meta` (Block List, Max: 1) (see [below for nested schema](#nestedblock--metadata--object_meta)) | ||
|
||
<a id="nestedblock--metadata--object_meta"></a> | ||
### Nested Schema for `metadata.object_meta` | ||
|
||
Optional: | ||
|
||
- `annotations` (Map of String) An unstructured map of keys and values stored on an object. | ||
- `environment` (String) The name of the environment the object belongs to. | ||
- `labels` (Map of String) A map of keys and values that can be used to organize and categorize objects. | ||
- `name` (String) The unique object name within its scope. | ||
|
||
Read-Only: | ||
|
||
- `revision` (String) An opaque resource revision. | ||
- `uid` (String) A unique identifier for each an object. | ||
|
||
|
||
|
||
<a id="nestedblock--spec"></a> | ||
### Nested Schema for `spec` | ||
|
||
Required: | ||
|
||
- `image` (String) Image is the image name. | ||
|
||
Optional: | ||
|
||
- `tag` (String) Tag is the image tag. | ||
|
||
Read-Only: | ||
|
||
- `digest` (String) Digest is the hash of the image. | ||
- `registry` (String) Registry is the registry that contains the image. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package container | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"slices" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
"github.com/nitrado/terraform-provider-ec/ec" | ||
"github.com/nitrado/terraform-provider-ec/pkg/resource" | ||
apierrors "gitlab.com/nitrado/b2b/ec/apicore/api/errors" | ||
metav1 "gitlab.com/nitrado/b2b/ec/apicore/apis/meta/v1" | ||
containerv1 "gitlab.com/nitrado/b2b/ec/core/pkg/api/container/v1" | ||
) | ||
|
||
// DataSourceImage returns the data source resource for an image. | ||
func DataSourceImage() *schema.Resource { | ||
return &schema.Resource{ | ||
Description: "Use this data source to access information about an existing Image.", | ||
ReadContext: dataSourceImageRead, | ||
Schema: imageSchema(), | ||
} | ||
} | ||
|
||
func dataSourceImageRead(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics { | ||
inst, _ := d.Get("instance").(string) | ||
clientSet, err := ec.ResolveClientSet(m, inst) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
branch := d.Get("metadata.0.branch").(string) | ||
name, hasName := d.GetOk("metadata.0.object_meta.0.name") | ||
image, hasImage := d.GetOk("spec.0.image") | ||
tag, hasTag := d.GetOk("spec.0.tag") | ||
|
||
var obj *containerv1.Image | ||
switch { | ||
case hasName: | ||
obj, err = clientSet.ContainerV1().Images(branch).Get(ctx, name.(string), metav1.GetOptions{}) | ||
if err != nil { | ||
switch { | ||
case apierrors.IsNotFound(err): | ||
d.SetId("") | ||
return nil | ||
default: | ||
return diag.FromErr(err) | ||
} | ||
} | ||
case hasImage: | ||
fieldSelector := map[string]string{ | ||
"spec.image": image.(string), | ||
} | ||
if hasTag { | ||
fieldSelector["spec.tag"] = tag.(string) | ||
} | ||
list, err := clientSet.ContainerV1().Images(branch).List(ctx, metav1.ListOptions{FieldSelector: fieldSelector}) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
if len(list.Items) == 0 { | ||
d.SetId("") | ||
return nil | ||
} | ||
latestImg := slices.MaxFunc(list.Items, func(a, b containerv1.Image) int { | ||
switch { | ||
case a.CreatedTimestamp.Before(b.CreatedTimestamp): | ||
return -1 | ||
case a.CreatedTimestamp.Equal(b.CreatedTimestamp): | ||
return 0 | ||
} | ||
return 1 | ||
}) | ||
obj = &latestImg | ||
default: | ||
return diag.FromErr(errors.New("either metadata.0.name or spec.0.image is required")) | ||
} | ||
|
||
d.SetId(obj.Branch + "/" + obj.Name) | ||
|
||
data, err := ec.Converter().Flatten(obj, imageSchema()) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
if err = resource.SetData(d, data); err != nil { | ||
return diag.FromErr(err) | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package container_test | ||
|
||
import ( | ||
"testing" | ||
"time" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||
"github.com/nitrado/terraform-provider-ec/ec/provider/providertest" | ||
metav1 "gitlab.com/nitrado/b2b/ec/apicore/apis/meta/v1" | ||
containerv1 "gitlab.com/nitrado/b2b/ec/core/pkg/api/container/v1" | ||
) | ||
|
||
func TestDataSourceImages(t *testing.T) { | ||
img1 := &containerv1.Image{ | ||
ImageObjectMeta: containerv1.ImageObjectMeta{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "my-image-1", | ||
CreatedTimestamp: time.Now().Add(-1 * time.Hour), | ||
}, | ||
Branch: "my-branch", | ||
}, | ||
Spec: containerv1.ImageSpec{ | ||
Image: "my-image-name", | ||
Tag: "my-tag1", | ||
}, | ||
} | ||
img2 := &containerv1.Image{ | ||
ImageObjectMeta: containerv1.ImageObjectMeta{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "my-image-2", | ||
CreatedTimestamp: time.Now(), | ||
}, | ||
Branch: "my-branch", | ||
}, | ||
Spec: containerv1.ImageSpec{ | ||
Image: "my-image-name", | ||
Tag: "my-tag2", | ||
}, | ||
} | ||
|
||
pf, _ := providertest.SetupProviderFactories(t, img1, img2) | ||
|
||
resource.Test(t, resource.TestCase{ | ||
IsUnitTest: true, | ||
ProviderFactories: pf, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testDataSourceImageNameConfigRead(), | ||
Check: resource.ComposeAggregateTestCheckFunc( | ||
resource.TestCheckResourceAttr("data.ec_container_image.by_name", "metadata.0.object_meta.0.name", "my-image-1"), | ||
resource.TestCheckResourceAttr("data.ec_container_image.by_name", "metadata.0.branch", "my-branch"), | ||
resource.TestCheckResourceAttr("data.ec_container_image.by_name", "spec.#", "1"), | ||
resource.TestCheckResourceAttr("data.ec_container_image.by_name", "spec.0.image", "my-image-name"), | ||
resource.TestCheckResourceAttr("data.ec_container_image.by_name", "spec.0.tag", "my-tag1"), | ||
), | ||
}, | ||
{ | ||
Config: testDataSourceImageSpecConfigRead(), | ||
Check: resource.ComposeAggregateTestCheckFunc( | ||
resource.TestCheckResourceAttr("data.ec_container_image.by_image", "metadata.0.object_meta.0.name", "my-image-2"), | ||
resource.TestCheckResourceAttr("data.ec_container_image.by_image", "metadata.0.branch", "my-branch"), | ||
resource.TestCheckResourceAttr("data.ec_container_image.by_image", "spec.#", "1"), | ||
resource.TestCheckResourceAttr("data.ec_container_image.by_image", "spec.0.image", "my-image-name"), | ||
resource.TestCheckResourceAttr("data.ec_container_image.by_image", "spec.0.tag", "my-tag2"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testDataSourceImageNameConfigRead() string { | ||
return `data "ec_container_image" "by_name" { | ||
metadata { | ||
object_meta { | ||
name = "my-image-1" | ||
} | ||
branch = "my-branch" | ||
} | ||
} | ||
` | ||
} | ||
|
||
func testDataSourceImageSpecConfigRead() string { | ||
return `data "ec_container_image" "by_image" { | ||
metadata { | ||
branch = "my-branch" | ||
} | ||
spec { | ||
image = "my-image-name" | ||
} | ||
} | ||
` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package container | ||
|
||
import ( | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
"github.com/nitrado/terraform-provider-ec/ec/meta" | ||
) | ||
|
||
// imageSchema is manually created, due to specific requirements. | ||
func imageSchema() map[string]*schema.Schema { | ||
return map[string]*schema.Schema{ | ||
"instance": { | ||
Type: schema.TypeString, | ||
Description: "Name is an instance name configured in the provider.", | ||
Optional: true, | ||
}, | ||
"metadata": { | ||
Type: schema.TypeList, | ||
Description: "Image object metadata.", | ||
Optional: true, | ||
MaxItems: 1, | ||
Elem: &schema.Resource{ | ||
Schema: map[string]*schema.Schema{ | ||
"branch": { | ||
Type: schema.TypeString, | ||
Description: "Branch defines the branch within which each name must be unique.", | ||
Required: true, | ||
}, | ||
"object_meta": { | ||
Type: schema.TypeList, | ||
Optional: true, | ||
MaxItems: 1, | ||
Elem: &schema.Resource{Schema: meta.Schema()}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
"spec": { | ||
Type: schema.TypeList, | ||
Description: "Spec defines the desired image.", | ||
Optional: true, | ||
MaxItems: 1, | ||
Elem: &schema.Resource{ | ||
Schema: map[string]*schema.Schema{ | ||
"digest": { | ||
Type: schema.TypeString, | ||
Description: "Digest is the hash of the image.", | ||
Computed: true, | ||
}, | ||
"image": { | ||
Type: schema.TypeString, | ||
Description: "Image is the image name.", | ||
Required: true, | ||
}, | ||
"registry": { | ||
Type: schema.TypeString, | ||
Description: "Registry is the registry that contains the image.", | ||
Computed: true, | ||
}, | ||
"tag": { | ||
Type: schema.TypeString, | ||
Description: "Tag is the image tag.", | ||
Optional: true, | ||
Computed: true, | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
} |
Oops, something went wrong.