Skip to content

Commit db1b2b9

Browse files
Feng Jiangvarmax2511
authored andcommitted
enable upload artifact with source file and fix bug in size_in_bytes
1 parent c33f2ac commit db1b2b9

File tree

6 files changed

+193
-9
lines changed

6 files changed

+193
-9
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 4.45.0 (Unreleased)
2+
3+
### Added
4+
- Support for source path based upload in `oci_generic_artifacts_content_artifact_by_path`
5+
16
## 4.44.0 (September 15, 2021)
27

38
### Added
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<body>
4+
<h1>Welcome</h1>
5+
</body>
6+
</html>

examples/artifacts/Repositories/repository.tf

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,22 @@ resource "oci_generic_artifacts_content_artifact_by_path" "test_artifact" {
3030
version = "1.0"
3131
content = "<a1>content</a1>"
3232
}
33-
34-
resource "oci_artifacts_generic_artifact" "test_generic_artifact" {
33+
resource "oci_artifacts_generic_artifact" "test_artifact" {
3534
artifact_id = oci_generic_artifacts_content_artifact_by_path.test_artifact.id
3635
}
3736

37+
38+
resource "oci_generic_artifacts_content_artifact_by_path" "test_artifact_by_source" {
39+
#Required
40+
artifact_path = "artifact_path"
41+
repository_id = oci_artifacts_repository.test_repository.id
42+
version = "2.0"
43+
source = "index.html"
44+
}
45+
resource "oci_artifacts_generic_artifact" "test_artifact_by_source" {
46+
artifact_id = oci_generic_artifacts_content_artifact_by_path.test_artifact_by_source.id
47+
}
48+
3849
data "oci_artifacts_repositories" "test_repositories" {
3950
#Required
4051
compartment_id = var.compartment_id

oci/generic_artifacts_content_artifact_by_path_resource.go

Lines changed: 80 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@ package oci
66
import (
77
"bytes"
88
"context"
9+
"crypto/sha256"
10+
"encoding/hex"
11+
"fmt"
912
"io/ioutil"
1013
"log"
14+
"os"
1115
"strconv"
1216

1317
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
@@ -41,10 +45,29 @@ func GenericArtifactsContentArtifactByPathResource() *schema.Resource {
4145
Required: true,
4246
ForceNew: true,
4347
},
48+
49+
// Optional
4450
"content": {
4551
Type: schema.TypeString,
46-
Required: true,
52+
Optional: true,
4753
ForceNew: true,
54+
StateFunc: func(body interface{}) string {
55+
v := body.(string)
56+
if v == "" {
57+
return ""
58+
}
59+
h := sha256.Sum256([]byte(v))
60+
return hex.EncodeToString(h[:])
61+
},
62+
ConflictsWith: []string{"source"},
63+
},
64+
"source": {
65+
Type: schema.TypeString,
66+
Optional: true,
67+
ForceNew: true,
68+
ConflictsWith: []string{"content"},
69+
StateFunc: getSourceFileState,
70+
ValidateFunc: validateSourceValue,
4871
},
4972

5073
// Computed
@@ -65,7 +88,7 @@ func GenericArtifactsContentArtifactByPathResource() *schema.Resource {
6588
Computed: true,
6689
},
6790
"size_in_bytes": {
68-
Type: schema.TypeInt,
91+
Type: schema.TypeString,
6992
Computed: true,
7093
},
7194
"state": {
@@ -172,6 +195,19 @@ func (s *GenericArtifactsContentArtifactByPathResourceCrud) Get() error {
172195
}
173196

174197
func (s *GenericArtifactsContentArtifactByPathResourceCrud) Create() error {
198+
if s.isSourceCreate() {
199+
return s.createArtifactBySource()
200+
}
201+
202+
return s.createArtifactByContent()
203+
}
204+
205+
func (s *GenericArtifactsContentArtifactByPathResourceCrud) isSourceCreate() bool {
206+
source, _ := s.D.GetOkExists("source")
207+
return source != ""
208+
}
209+
210+
func (s *GenericArtifactsContentArtifactByPathResourceCrud) createArtifactByContent() error {
175211
request := oci_generic_artifacts_content.PutGenericArtifactContentByPathRequest{}
176212

177213
if genericArtifactContentBody, ok := s.D.GetOkExists("content"); ok {
@@ -204,6 +240,48 @@ func (s *GenericArtifactsContentArtifactByPathResourceCrud) Create() error {
204240
return nil
205241
}
206242

243+
func (s *GenericArtifactsContentArtifactByPathResourceCrud) createArtifactBySource() error {
244+
request := oci_generic_artifacts_content.PutGenericArtifactContentByPathRequest{}
245+
246+
source, ok := s.D.GetOkExists("source")
247+
if !ok {
248+
return fmt.Errorf("the source is not specified")
249+
}
250+
sourcePath := source.(string)
251+
sourceFile, err := os.Open(sourcePath)
252+
if err != nil {
253+
return fmt.Errorf("the specified source is not available: %q", err)
254+
}
255+
256+
defer safeClose(sourceFile, &err)
257+
258+
request.GenericArtifactContentBody = sourceFile
259+
260+
if artifactPath, ok := s.D.GetOkExists("artifact_path"); ok {
261+
tmp := artifactPath.(string)
262+
request.ArtifactPath = &tmp
263+
}
264+
265+
if repositoryId, ok := s.D.GetOkExists("repository_id"); ok {
266+
tmp := repositoryId.(string)
267+
request.RepositoryId = &tmp
268+
}
269+
270+
if version, ok := s.D.GetOkExists("version"); ok {
271+
tmp := version.(string)
272+
request.Version = &tmp
273+
}
274+
275+
request.RequestMetadata.RetryPolicy = getRetryPolicy(s.DisableNotFoundRetries, "generic_artifacts_content")
276+
277+
response, err := s.Client.PutGenericArtifactContentByPath(context.Background(), request)
278+
if err != nil {
279+
return err
280+
}
281+
s.Res = &response
282+
return nil
283+
}
284+
207285
func (s *GenericArtifactsContentArtifactByPathResourceCrud) SetData() error {
208286

209287
if s.Content != nil {

oci/generic_artifacts_content_artifact_by_path_test.go

Lines changed: 86 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ package oci
55

66
import (
77
"fmt"
8+
"io/ioutil"
9+
"os"
810
"strconv"
911
"testing"
1012

@@ -32,6 +34,8 @@ var (
3234
}
3335

3436
ArtifactByPathResourceDependencies = generateResourceFromRepresentationMap("oci_artifacts_repository", "test_repository", Required, Create, repositoryRepresentation)
37+
// the deletion of oci_generic_artifacts_content_artifact_by_path is done by oci_artifacts_generic_artifact
38+
GenericArtifactManager = generateResourceFromRepresentationMap("oci_artifacts_generic_artifact", "test_generic_artifact", Required, Create, genericArtifactRepresentation)
3539
)
3640

3741
// issue-routing-tag: generic_artifacts_content/default
@@ -57,7 +61,7 @@ func TestGenericArtifactsContentArtifactByPathResource_basic(t *testing.T) {
5761
// verify create
5862
{
5963
Config: config + compartmentIdVariableStr + ArtifactByPathResourceDependencies +
60-
generateResourceFromRepresentationMap("oci_generic_artifacts_content_artifact_by_path", "test_artifact_by_path", Required, Create, artifactByPathRepresentation),
64+
generateResourceFromRepresentationMap("oci_generic_artifacts_content_artifact_by_path", "test_artifact_by_path", Required, Create, artifactByPathRepresentation) + GenericArtifactManager,
6165
Check: ComposeAggregateTestCheckFuncWrapper(
6266

6367
func(s *terraform.State) (err error) {
@@ -75,7 +79,7 @@ func TestGenericArtifactsContentArtifactByPathResource_basic(t *testing.T) {
7579
// verify updates to updatable parameters
7680
{
7781
Config: config + compartmentIdVariableStr + ArtifactByPathResourceDependencies +
78-
generateResourceFromRepresentationMap("oci_generic_artifacts_content_artifact_by_path", "test_artifact_by_path", Optional, Update, artifactByPathRepresentation),
82+
generateResourceFromRepresentationMap("oci_generic_artifacts_content_artifact_by_path", "test_artifact_by_path", Optional, Update, artifactByPathRepresentation) + GenericArtifactManager,
7983
Check: ComposeAggregateTestCheckFuncWrapper(
8084

8185
func(s *terraform.State) (err error) {
@@ -87,11 +91,12 @@ func TestGenericArtifactsContentArtifactByPathResource_basic(t *testing.T) {
8791
},
8892
),
8993
},
94+
9095
// verify singular datasource
9196
{
9297
Config: config +
9398
generateDataSourceFromRepresentationMap("oci_generic_artifacts_content_artifact_by_path", "test_artifact_by_path", Required, Create, artifactByPathSingularDataSourceRepresentation) +
94-
compartmentIdVariableStr + ArtifactByPathResourceConfig,
99+
compartmentIdVariableStr + ArtifactByPathResourceConfig + GenericArtifactManager,
95100
Check: ComposeAggregateTestCheckFuncWrapper(
96101
resource.TestCheckResourceAttr(singularDatasourceName, "artifact_path", "artifactPath"),
97102
resource.TestCheckResourceAttrSet(singularDatasourceName, "repository_id"),
@@ -100,3 +105,81 @@ func TestGenericArtifactsContentArtifactByPathResource_basic(t *testing.T) {
100105
},
101106
})
102107
}
108+
109+
const (
110+
tempFilePrefix = "small-"
111+
tempFileSize = 2e5
112+
tempFileSha256 = "4cbbd9be0cba685835755f827758705db5a413c5494c34262cd25946a73e7582"
113+
)
114+
115+
func createTmpFile() (string, error) {
116+
tempFile, err := ioutil.TempFile(os.TempDir(), tempFilePrefix)
117+
if err != nil {
118+
return "", err
119+
}
120+
if err := tempFile.Truncate(tempFileSize); err != nil {
121+
return "", err
122+
}
123+
return tempFile.Name(), nil
124+
}
125+
126+
var (
127+
artifactByPathSourceRepresentation = map[string]interface{}{
128+
"artifact_path": Representation{repType: Required, create: `artifactPath`},
129+
"repository_id": Representation{repType: Required, create: `${oci_artifacts_repository.test_repository.id}`},
130+
"version": Representation{repType: Required, create: `1.0`},
131+
"source": Representation{repType: Required, create: ``},
132+
}
133+
)
134+
135+
// issue-routing-tag: generic_artifacts_content/default
136+
func TestGenericArtifactsContentArtifactByPathResource_uploadFile(t *testing.T) {
137+
httpreplay.SetScenario("TestGenericArtifactsContentArtifactByPathResource_uploadFile")
138+
defer httpreplay.SaveScenario()
139+
140+
provider := testAccProvider
141+
config := testProviderConfig()
142+
143+
compartmentId := getEnvSettingWithBlankDefault("compartment_ocid")
144+
compartmentIdVariableStr := fmt.Sprintf("variable \"compartment_id\" { default = \"%s\" }\n", compartmentId)
145+
146+
resourceName := "oci_generic_artifacts_content_artifact_by_path.test_artifact_by_path"
147+
148+
tempFilePath, err := createTmpFile()
149+
if err != nil {
150+
t.Fatalf("Unable to create file to upload. Error: %q", err)
151+
}
152+
153+
var resId, _ string
154+
// Save TF content to create resource with only required properties. This has to be exactly the same as the config part in the create step in the test.
155+
saveConfigContent(config+compartmentIdVariableStr+ArtifactByPathResourceDependencies+
156+
generateResourceFromRepresentationMap("oci_generic_artifacts_content_artifact_by_path", "test_artifact_by_path", Required, Create, artifactByPathRepresentation), "genericartifactscontent", "artifactByPath", t)
157+
158+
resource.Test(t, resource.TestCase{
159+
PreCheck: func() { testAccPreCheck(t) },
160+
Providers: map[string]terraform.ResourceProvider{
161+
"oci": provider,
162+
},
163+
Steps: []resource.TestStep{
164+
// verify create
165+
{
166+
Config: config + compartmentIdVariableStr + ArtifactByPathResourceDependencies +
167+
generateResourceFromRepresentationMap("oci_generic_artifacts_content_artifact_by_path", "test_artifact_by_path", Required, Create,
168+
getUpdatedRepresentationCopy("source", Representation{repType: Required, create: tempFilePath}, artifactByPathSourceRepresentation)) + GenericArtifactManager,
169+
Check: ComposeAggregateTestCheckFuncWrapper(
170+
resource.TestCheckResourceAttr(resourceName, "sha256", tempFileSha256),
171+
resource.TestCheckResourceAttr(resourceName, "size_in_bytes", strconv.Itoa(tempFileSize)),
172+
func(s *terraform.State) (err error) {
173+
resId, err = fromInstanceState(s, resourceName, "id")
174+
if isEnableExportCompartment, _ := strconv.ParseBool(getEnvSettingWithDefault("enable_export_compartment", "true")); isEnableExportCompartment {
175+
if errExport := testExportCompartmentWithResourceName(&resId, &compartmentId, resourceName); errExport != nil {
176+
return errExport
177+
}
178+
}
179+
return err
180+
},
181+
),
182+
},
183+
},
184+
})
185+
}

website/docs/r/generic_artifacts_content_artifact_by_path.html.markdown

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ resource "oci_generic_artifacts_content_artifact_by_path" "test_artifact_by_path
2222
artifact_path = var.artifact_path
2323
repository_id = oci_artifacts_repository.test_repository.id
2424
version = var.version
25-
content = var.content
25+
source = var.source
2626
}
2727
```
2828

@@ -33,7 +33,8 @@ The following arguments are supported:
3333
* `artifact_path` - (Required) A user-defined path to describe the location of an artifact. You can use slashes to organize the repository, but slashes do not create a directory structure. An artifact path does not include an artifact version.
3434
* `version` - (Required) A user-defined string to describe the artifact version. Example: `1.1.0` or `1.2-beta-2`
3535
* `repository_id` - (Required) The [OCID](/iaas/Content/General/Concepts/identifiers.htm) of the repository.
36-
* `content` - (Required) The content of the artifact
36+
* `source` - (Optional) A path to a file on the local system to be uploaded as the artifact. Cannot be defined if `content` is defined.
37+
* `content` - (Optional) Content to be uploaded as the artifact. Cannot be defined if `source` is defined.
3738

3839

3940
** IMPORTANT **

0 commit comments

Comments
 (0)