Skip to content

Commit 1cd51b8

Browse files
committed
feat(SWR): support to get image tags by v3 api
1 parent 651d21e commit 1cd51b8

File tree

4 files changed

+366
-0
lines changed

4 files changed

+366
-0
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
---
2+
subcategory: "Software Repository for Container (SWR)"
3+
layout: "huaweicloud"
4+
page_title: "HuaweiCloud: huaweicloud_swrv3_image_tags"
5+
description: |-
6+
Use this data source to get the list of SWR image tags.
7+
---
8+
9+
# huaweicloud_swrv3_image_tags
10+
11+
Use this data source to get the list of SWR image tags.
12+
13+
## Example Usage
14+
15+
```hcl
16+
variable "organization" {}
17+
variable "repository" {}
18+
19+
data "huaweicloud_swrv3_image_tags" "test" {
20+
organization = var.organization
21+
repository = var.repository
22+
}
23+
```
24+
25+
## Argument Reference
26+
27+
The following arguments are supported:
28+
29+
* `region` - (Optional, String) Specifies the region in which to query the resource.
30+
If omitted, the provider-level region will be used.
31+
32+
* `organization` - (Required, String) Specifies the name of the organization.
33+
34+
* `repository` - (Required, String) Specifies the name of the repository.
35+
36+
* `tag` - (Optional, String) Specifies the source tag.
37+
38+
* `with_manifest` - (Optional, Bool) Specifies whether to get the manifest infos.
39+
40+
## Attribute Reference
41+
42+
In addition to all arguments above, the following attributes are exported:
43+
44+
* `id` - The data source ID.
45+
46+
* `tags` - Indicates the tag list.
47+
48+
The [tags](#tags_struct) structure is documented below.
49+
50+
<a name="tags_struct"></a>
51+
The `tags` block supports:
52+
53+
* `id` - Indicates the tag ID.
54+
55+
* `schema` - Indicates the docker schema.
56+
57+
* `size` - Indicates the image size.
58+
59+
* `created` - Indicates the last update time.
60+
61+
* `updated` - Indicates the last update time.
62+
63+
* `tag` - Indicates the image tag.
64+
65+
* `digest` - Indicates the image digest.
66+
67+
* `path` - Indicates the image pull path.
68+
69+
* `internal_path` - Indicates the image internal pull path.
70+
71+
* `repo_id` - Indicates the repository ID.
72+
73+
* `image_id` - Indicates the image ID.
74+
75+
* `manifest` - Indicates the image manifest.
76+
77+
* `is_trusted` - Indicates whether the image is trusted.
78+
79+
* `tag_type` - Indicates the tag type.

huaweicloud/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1986,6 +1986,7 @@ func Provider() *schema.Provider {
19861986
"huaweicloud_swrv3_repositories": swr.DataSourceSwrv3Repositories(),
19871987
"huaweicloud_swr_shared_repositories": swr.DataSourceSharedRepositories(),
19881988
"huaweicloud_swrv3_shared_repositories": swr.DataSourceSwrv3SharedRepositories(),
1989+
"huaweicloud_swrv3_image_tags": swr.DataSourceSwrv3ImageTags(),
19891990
"huaweicloud_swr_image_auto_sync_jobs": swr.DataSourceSwrImageAutoSyncJobs(),
19901991
"huaweicloud_swr_image_triggers": swr.DataSourceImageTriggers(),
19911992
"huaweicloud_swr_image_tags": swr.DataSourceImageTags(),
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package swr
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
8+
9+
"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance"
10+
)
11+
12+
func TestAccDataSourceSwrv3ImageTags_basic(t *testing.T) {
13+
dataSource := "data.huaweicloud_swrv3_image_tags.test"
14+
rName := acceptance.RandomAccResourceName()
15+
dc := acceptance.InitDataSourceCheck(dataSource)
16+
17+
resource.ParallelTest(t, resource.TestCase{
18+
PreCheck: func() {
19+
acceptance.TestAccPreCheck(t)
20+
acceptance.TestAccPreCheckSwrRepository(t)
21+
acceptance.TestAccPreCheckSwrOrigination(t)
22+
},
23+
ProviderFactories: acceptance.TestAccProviderFactories,
24+
Steps: []resource.TestStep{
25+
{
26+
Config: testDataSourceSwrv3ImageTags_basic(rName),
27+
Check: resource.ComposeTestCheckFunc(
28+
dc.CheckResourceExists(),
29+
resource.TestCheckResourceAttrSet(dataSource, "tags.#"),
30+
resource.TestCheckResourceAttrSet(dataSource, "tags.0.id"),
31+
resource.TestCheckResourceAttrSet(dataSource, "tags.0.schema"),
32+
resource.TestCheckResourceAttrSet(dataSource, "tags.0.size"),
33+
resource.TestCheckResourceAttrSet(dataSource, "tags.0.tag"),
34+
resource.TestCheckResourceAttrSet(dataSource, "tags.0.digest"),
35+
resource.TestCheckResourceAttrSet(dataSource, "tags.0.path"),
36+
resource.TestCheckResourceAttrSet(dataSource, "tags.0.internal_path"),
37+
resource.TestCheckResourceAttrSet(dataSource, "tags.0.repo_id"),
38+
resource.TestCheckResourceAttrSet(dataSource, "tags.0.image_id"),
39+
resource.TestCheckResourceAttrSet(dataSource, "tags.0.created"),
40+
resource.TestCheckResourceAttrSet(dataSource, "tags.0.updated"),
41+
resource.TestCheckResourceAttrSet(dataSource, "tags.0.manifest"),
42+
resource.TestCheckResourceAttrSet(dataSource, "tags.0.is_trusted"),
43+
resource.TestCheckResourceAttrSet(dataSource, "tags.0.tag_type"),
44+
45+
resource.TestCheckOutput("tag_filter_is_useful", "true"),
46+
),
47+
},
48+
},
49+
})
50+
}
51+
52+
func testDataSourceSwrv3ImageTags_basic(name string) string {
53+
return fmt.Sprintf(`
54+
data "huaweicloud_swrv3_image_tags" "test" {
55+
organization = "%[1]s"
56+
repository = "%[2]s"
57+
with_manifest = true
58+
}
59+
60+
data "huaweicloud_swrv3_image_tags" "filter_by_tag" {
61+
organization = "%[1]s"
62+
repository = "%[2]s"
63+
tag = data.huaweicloud_swrv3_image_tags.test.tags[0].tag
64+
}
65+
66+
output "tag_filter_is_useful" {
67+
value = length(data.huaweicloud_swrv3_image_tags.filter_by_tag.tags) == 1
68+
}
69+
`, acceptance.HW_SWR_ORGANIZATION, acceptance.HW_SWR_REPOSITORY)
70+
}
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
// Generated by PMS #1014
2+
package swr
3+
4+
import (
5+
"context"
6+
"strings"
7+
8+
"github.com/hashicorp/go-multierror"
9+
"github.com/hashicorp/go-uuid"
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
12+
"github.com/tidwall/gjson"
13+
14+
"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config"
15+
"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/helper/httphelper"
16+
"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/helper/schemas"
17+
"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/utils"
18+
)
19+
20+
func DataSourceSwrv3ImageTags() *schema.Resource {
21+
return &schema.Resource{
22+
ReadContext: dataSourceSwrv3ImageTagsRead,
23+
24+
Schema: map[string]*schema.Schema{
25+
"region": {
26+
Type: schema.TypeString,
27+
Optional: true,
28+
Computed: true,
29+
Description: `Specifies the region in which to query the resource. If omitted, the provider-level region will be used.`,
30+
},
31+
"organization": {
32+
Type: schema.TypeString,
33+
Required: true,
34+
Description: `Specifies the name of the organization.`,
35+
},
36+
"repository": {
37+
Type: schema.TypeString,
38+
Required: true,
39+
Description: `Specifies the name of the repository.`,
40+
},
41+
"tag": {
42+
Type: schema.TypeString,
43+
Optional: true,
44+
Description: `Specifies the source tag.`,
45+
},
46+
"with_manifest": {
47+
Type: schema.TypeBool,
48+
Optional: true,
49+
Description: `Specifies whether to get the manifest infos.`,
50+
},
51+
"tags": {
52+
Type: schema.TypeList,
53+
Computed: true,
54+
Description: `Indicates the tag list.`,
55+
Elem: &schema.Resource{
56+
Schema: map[string]*schema.Schema{
57+
"id": {
58+
Type: schema.TypeInt,
59+
Computed: true,
60+
Description: `Indicates the tag ID.`,
61+
},
62+
"schema": {
63+
Type: schema.TypeInt,
64+
Computed: true,
65+
Description: `Indicates the docker schema.`,
66+
},
67+
"size": {
68+
Type: schema.TypeInt,
69+
Computed: true,
70+
Description: `Indicates the image size.`,
71+
},
72+
"created": {
73+
Type: schema.TypeString,
74+
Computed: true,
75+
Description: `Indicates the last update time.`,
76+
},
77+
"updated": {
78+
Type: schema.TypeString,
79+
Computed: true,
80+
Description: `Indicates the last update time.`,
81+
},
82+
"tag": {
83+
Type: schema.TypeString,
84+
Computed: true,
85+
Description: `Indicates the image tag.`,
86+
},
87+
"digest": {
88+
Type: schema.TypeString,
89+
Computed: true,
90+
Description: `Indicates the image digest.`,
91+
},
92+
"path": {
93+
Type: schema.TypeString,
94+
Computed: true,
95+
Description: `Indicates the image pull path.`,
96+
},
97+
"internal_path": {
98+
Type: schema.TypeString,
99+
Computed: true,
100+
Description: `Indicates the image internal pull path.`,
101+
},
102+
"repo_id": {
103+
Type: schema.TypeInt,
104+
Computed: true,
105+
Description: `Indicates the repository ID.`,
106+
},
107+
"image_id": {
108+
Type: schema.TypeString,
109+
Computed: true,
110+
Description: `Indicates the image ID.`,
111+
},
112+
"manifest": {
113+
Type: schema.TypeString,
114+
Computed: true,
115+
Description: `Indicates the image manifest.`,
116+
},
117+
"is_trusted": {
118+
Type: schema.TypeBool,
119+
Computed: true,
120+
Description: `Indicates whether the image is trusted.`,
121+
},
122+
"tag_type": {
123+
Type: schema.TypeInt,
124+
Computed: true,
125+
Description: `Indicates the tag type.`,
126+
},
127+
},
128+
},
129+
},
130+
},
131+
}
132+
}
133+
134+
type v3ImageTagsDSWrapper struct {
135+
*schemas.ResourceDataWrapper
136+
Config *config.Config
137+
}
138+
139+
func newv3ImageTagsDSWrapper(d *schema.ResourceData, meta interface{}) *v3ImageTagsDSWrapper {
140+
return &v3ImageTagsDSWrapper{
141+
ResourceDataWrapper: schemas.NewSchemaWrapper(d),
142+
Config: meta.(*config.Config),
143+
}
144+
}
145+
146+
func dataSourceSwrv3ImageTagsRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
147+
wrapper := newv3ImageTagsDSWrapper(d, meta)
148+
listRepositoryTagRst, err := wrapper.ListRepositoryTag()
149+
if err != nil {
150+
return diag.FromErr(err)
151+
}
152+
153+
err = wrapper.listRepositoryTagToSchema(listRepositoryTagRst)
154+
if err != nil {
155+
return diag.FromErr(err)
156+
}
157+
158+
id, err := uuid.GenerateUUID()
159+
if err != nil {
160+
return diag.FromErr(err)
161+
}
162+
d.SetId(id)
163+
return nil
164+
}
165+
166+
// @API SWR GET /v3/manage/namespaces/{namespace}/repos/{repository}/tags
167+
func (w *v3ImageTagsDSWrapper) ListRepositoryTag() (*gjson.Result, error) {
168+
client, err := w.NewClient(w.Config, "swr")
169+
if err != nil {
170+
return nil, err
171+
}
172+
173+
uri := "/v3/manage/namespaces/{namespace}/repos/{repository}/tags"
174+
uri = strings.ReplaceAll(uri, "{namespace}", w.Get("organization").(string))
175+
uri = strings.ReplaceAll(uri, "{repository}", w.Get("repository").(string))
176+
params := map[string]any{
177+
"tag": w.Get("tag"),
178+
"with_manifest": w.Get("with_manifest"),
179+
}
180+
params = utils.RemoveNil(params)
181+
return httphelper.New(client).
182+
Method("GET").
183+
URI(uri).
184+
Query(params).
185+
MarkerPager("tags", "next_marker", "marker").
186+
Request().
187+
Result()
188+
}
189+
190+
func (w *v3ImageTagsDSWrapper) listRepositoryTagToSchema(body *gjson.Result) error {
191+
d := w.ResourceData
192+
mErr := multierror.Append(nil,
193+
d.Set("region", w.Config.GetRegion(w.ResourceData)),
194+
d.Set("tags", schemas.SliceToList(body.Get("tags"),
195+
func(tags gjson.Result) any {
196+
return map[string]any{
197+
"id": tags.Get("id").Value(),
198+
"schema": tags.Get("schema").Value(),
199+
"size": tags.Get("size").Value(),
200+
"created": tags.Get("created").Value(),
201+
"updated": tags.Get("updated").Value(),
202+
"tag": tags.Get("tag").Value(),
203+
"digest": tags.Get("digest").Value(),
204+
"path": tags.Get("path").Value(),
205+
"internal_path": tags.Get("internal_path").Value(),
206+
"repo_id": tags.Get("repo_id").Value(),
207+
"image_id": tags.Get("image_id").Value(),
208+
"manifest": tags.Get("manifest").Value(),
209+
"is_trusted": tags.Get("is_trusted").Value(),
210+
"tag_type": tags.Get("tag_type").Value(),
211+
}
212+
},
213+
)),
214+
)
215+
return mErr.ErrorOrNil()
216+
}

0 commit comments

Comments
 (0)