Skip to content

Commit

Permalink
Merge pull request #933 from jfrog/GH-896-add-upload-artifact-resource
Browse files Browse the repository at this point in the history
Add new artifactory_artifact resource
  • Loading branch information
alexhung authored Apr 12, 2024
2 parents 6296a0e + f694f16 commit 9f83e9c
Show file tree
Hide file tree
Showing 82 changed files with 727 additions and 170 deletions.
7 changes: 5 additions & 2 deletions .jfrog-pipelines/TFproviderTest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,22 +62,25 @@ pipelines:
- name: pre_build_approval
environmentVariables:
USE_LATEST_RT_VERSION: "true"
ARTIFACTORY_TEST_VERSION: 7.49.8
ARTIFACTORY_TEST_VERSION: 7.77.9
SONAR_SCANNER_VERSION: 4.7.0.2747
SONAR_SCANNER_HOME: $HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION-linux
SONAR_SCANNER_OPTS: "-server"
stepletMultipliers:
environmentVariables:
- directory: ./pkg/artifactory/datasource
- directory: ./pkg/artifactory/datasource/artifact
- directory: ./pkg/artifactory/datasource/repository
- directory: ./pkg/artifactory/datasource/repository/federated
- directory: ./pkg/artifactory/datasource/repository/local
- directory: ./pkg/artifactory/datasource/repository/remote
- directory: ./pkg/artifactory/datasource/repository/virtual
- directory: ./pkg/artifactory/datasource/security
- directory: ./pkg/artifactory/datasource/user
- directory: ./pkg/artifactory/provider
- directory: ./pkg/artifactory/resource
- directory: ./pkg/artifactory/resource/configuration
- directory: ./pkg/artifactory/resource/replication
- directory: ./pkg/artifactory/resource/repository
- directory: ./pkg/artifactory/resource/repository/federated
- directory: ./pkg/artifactory/resource/repository/local
- directory: ./pkg/artifactory/resource/repository/remote
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## 10.6.0 (Apr 12, 2024)

FEATURES:

* **New Resource:** `artifactory_artifact` for uploading artifact to repository. Issue: [#896](https://github.com/jfrog/terraform-provider-artifactory/issues/896) PR: [#933](https://github.com/jfrog/terraform-provider-artifactory/pull/933)

BUG FIXES:

* provider: Fix crash when provider checks for Artifactory license fails due to networking issue. Issue: [#930](https://github.com/jfrog/terraform-provider-artifactory/issues/930) PR: [#933](https://github.com/jfrog/terraform-provider-artifactory/pull/933)

## 10.5.1 (Apr 10, 2024)

BUG FIXES:
Expand Down
42 changes: 42 additions & 0 deletions docs/resources/artifact.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "artifactory_artifact Resource - terraform-provider-artifactory"
subcategory: ""
description: |-
Provides a resource for deploying artifact to Artifactory repository. Support deploying a single artifact only. Changes to repository or path attributes will trigger a recreation of the resource (i.e. delete then create). See JFrog documentation https://jfrog.com/help/r/jfrog-artifactory-documentation/deploy-a-single-artifact for more details.
---

# artifactory_artifact (Resource)

Provides a resource for deploying artifact to Artifactory repository. Support deploying a single artifact only. Changes to `repository` or `path` attributes will trigger a recreation of the resource (i.e. delete then create). See [JFrog documentation](https://jfrog.com/help/r/jfrog-artifactory-documentation/deploy-a-single-artifact) for more details.

## Example Usage

```terraform
resource "artifactory_artifact" "my-artifact" {
repository = "my-generic-local"
path = "/my-path/my-file.zip"
file_path = "/path/to/my-file.zip"
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `file_path` (String) Path to the source file.
- `path` (String) The relative path in the target repository. Must begin with a '/'. You can add key-value matrix parameters to deploy the artifacts with properties. For more details, please refer to [Introducing Matrix Parameters](https://jfrog.com/help/r/jfrog-artifactory-documentation/using-properties-in-deployment-and-resolution).
- `repository` (String) Name of the respository.

### Read-Only

- `checksum_md5` (String) MD5 checksum of the artifact.
- `checksum_sha1` (String) SHA1 checksum of the artifact.
- `checksum_sha256` (String) SHA256 checksum of the artifact.
- `created` (String) Timestamp when artifact is created.
- `created_by` (String) User who deploys the artifact.
- `download_uri` (String) Download URI of the artifact.
- `mime_type` (String) MIME type of the artifact.
- `size` (Number) Size of the artifact, in bytes.
- `uri` (String) URI of the artifact.
5 changes: 5 additions & 0 deletions examples/resources/artifactory_artifact/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
resource "artifactory_artifact" "my-artifact" {
repository = "my-generic-local"
path = "/my-path/my-file.zip"
file_path = "/path/to/my-file.zip"
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ require (
github.com/hashicorp/terraform-plugin-mux v0.12.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.30.0
github.com/hashicorp/terraform-plugin-testing v1.5.1
github.com/jfrog/terraform-provider-shared v1.22.4
github.com/jfrog/terraform-provider-shared v1.24.0
github.com/samber/lo v1.39.0
github.com/sethvargo/go-password v0.2.0
github.com/stretchr/testify v1.8.4
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM=
github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jfrog/terraform-provider-shared v1.22.4 h1:WjJKEzFPKgfnQVg0GXE+6x64sSqDWXKkZeHEKW/x+sk=
github.com/jfrog/terraform-provider-shared v1.22.4/go.mod h1:OozwvfahZU4Q9u3kXdpQI3h/Etrs2DXoouQDrpxB1cQ=
github.com/jfrog/terraform-provider-shared v1.24.0 h1:VItpElBn9Jku8gtN7DhOURUIyoUYYw8R9erPBPgKwv8=
github.com/jfrog/terraform-provider-shared v1.24.0/go.mod h1:OozwvfahZU4Q9u3kXdpQI3h/Etrs2DXoouQDrpxB1cQ=
github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo=
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
Expand Down
6 changes: 3 additions & 3 deletions pkg/acctest/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ func VerifyDeleted(id string, check CheckFun) func(*terraform.State) error {
return fmt.Errorf("provider is not initialized. Please PreCheck() is included in your acceptance test")
}

providerMeta := Provider.Meta().(util.ProvderMetadata)
providerMeta := Provider.Meta().(util.ProviderMetadata)

resp, err := check(rs.Primary.ID, providerMeta.Client.R())
if err != nil {
Expand Down Expand Up @@ -252,7 +252,7 @@ func GetValidRandomDefaultRepoLayoutRef() string {
var updateProxiesConfig = func(t *testing.T, proxyKey string, getProxiesBody func() []byte) {
body := getProxiesBody()
restyClient := GetTestResty(t)
metadata := util.ProvderMetadata{Client: restyClient}
metadata := util.ProviderMetadata{Client: restyClient}
err := configuration.SendConfigurationPatch(body, metadata)
if err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -368,7 +368,7 @@ func CompareArtifactoryVersions(t *testing.T, instanceVersions string) (bool, er
return false, err
}

meta := Provider.Meta().(util.ProvderMetadata)
meta := Provider.Meta().(util.ProviderMetadata)
runtimeVersion, err := version.NewVersion(meta.ArtifactoryVersion)
if err != nil {
return false, err
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ func downloadUsingFileInfo(ctx context.Context, outputPath string, forceOverwrit
"path": path,
})

client := m.(util.ProvderMetadata).Client
client := m.(util.ProviderMetadata).Client
// switch to using Sprintf because Resty's SetPathParams() escape the path
// see https://github.com/go-resty/resty/blob/v2.7.0/middleware.go#L33
// should use url.JoinPath() eventually in go 1.20
Expand Down Expand Up @@ -251,7 +251,7 @@ func downloadUsingFileInfo(ctx context.Context, outputPath string, forceOverwrit
"fileInfo.DownloadUri": fileInfo.DownloadUri,
"outputPath": outputPath,
})
_, err = m.(util.ProvderMetadata).Client.R().SetOutput(outputPath).Get(fileInfo.DownloadUri)
_, err = m.(util.ProviderMetadata).Client.R().SetOutput(outputPath).Get(fileInfo.DownloadUri)
if err != nil {
return fileInfo, err
}
Expand Down Expand Up @@ -303,7 +303,7 @@ func downloadWithoutChecks(ctx context.Context, outputPath string, forceOverwrit
"outputPath": outputPath,
})

client := m.(util.ProvderMetadata).Client
client := m.(util.ProviderMetadata).Client
// switch to using Sprintf because Resty's SetPathParams() escape the path
// see https://github.com/go-resty/resty/blob/v2.7.0/middleware.go#L33
// should use url.JoinPath() eventually in go 1.20
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func NewFileListDataSource() datasource.DataSource {
}

type FileListDataSource struct {
ProviderData util.ProvderMetadata
ProviderData util.ProviderMetadata
}

type FileListDataSourceModel struct {
Expand Down Expand Up @@ -218,7 +218,7 @@ func (d *FileListDataSource) Configure(ctx context.Context, req datasource.Confi
if req.ProviderData == nil {
return
}
d.ProviderData = req.ProviderData.(util.ProvderMetadata)
d.ProviderData = req.ProviderData.(util.ProviderMetadata)
}

func bool2String(v bool) string {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func dataSourceFileInfoRead(_ context.Context, d *schema.ResourceData, m interfa
path := d.Get("path").(string)

fileInfo := FileInfo{}
resp, err := m.(util.ProvderMetadata).Client.R().
resp, err := m.(util.ProviderMetadata).Client.R().
SetResult(&fileInfo).
SetPathParams(map[string]string{
"repoKey": repo,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func NewRepositoriesDataSource() datasource.DataSource {
}

type RepositoriesDataSource struct {
ProviderData util.ProvderMetadata
ProviderData util.ProviderMetadata
}

type RepositoriesDataSourceModel struct {
Expand Down Expand Up @@ -134,7 +134,7 @@ func (d *RepositoriesDataSource) Configure(ctx context.Context, req datasource.C
if req.ProviderData == nil {
return
}
d.ProviderData = req.ProviderData.(util.ProvderMetadata)
d.ProviderData = req.ProviderData.(util.ProviderMetadata)
}

func (d *RepositoriesDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/artifactory/datasource/repository/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func MkRepoReadDataSource(pack packer.PackFunc, construct repository.Constructor

key := d.Get("key").(string)
// repo must be a pointer
resp, err := m.(util.ProvderMetadata).Client.R().
resp, err := m.(util.ProviderMetadata).Client.R().
SetResult(repo).
SetPathParam("key", key).
Get(repository.RepositoriesEndpoint)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func DataSourceArtifactoryGroup() *schema.Resource {
group := Group{}
name := d.Get("name").(string)
includeUsers := d.Get("include_users").(string)
resp, err := m.(util.ProvderMetadata).Client.R().SetResult(&group).SetQueryParam("includeUsers", includeUsers).Get(security.GroupsEndpoint + name)
resp, err := m.(util.ProviderMetadata).Client.R().SetResult(&group).SetQueryParam("includeUsers", includeUsers).Get(security.GroupsEndpoint + name)

if err != nil {
return diag.FromErr(err)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ func DataSourceArtifactoryPermissionTarget() *schema.Resource {
dataSourcePermissionTargetRead := func(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
permissionTarget := new(PermissionTargetParams)
targetName := d.Get("name").(string)
resp, err := m.(util.ProvderMetadata).Client.R().SetResult(permissionTarget).Get(security.PermissionsEndPoint + targetName)
resp, err := m.(util.ProviderMetadata).Client.R().SetResult(permissionTarget).Get(security.PermissionsEndPoint + targetName)

if err != nil {
return diag.FromErr(err)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ func DataSourceArtifactoryUser() *schema.Resource {
var userObj user.User
var artifactoryError artifactory.ArtifactoryErrorsResponse
resp, err := user.ReadUser(
m.(util.ProvderMetadata).Client.R(),
m.(util.ProvderMetadata).ArtifactoryVersion,
m.(util.ProviderMetadata).Client.R(),
m.(util.ProviderMetadata).ArtifactoryVersion,
userName,
&userObj,
&artifactoryError)
Expand Down
13 changes: 6 additions & 7 deletions pkg/artifactory/provider/framework.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework/types"
datasource_artifact "github.com/jfrog/terraform-provider-artifactory/v10/pkg/artifactory/datasource/artifact"
datasource_repository "github.com/jfrog/terraform-provider-artifactory/v10/pkg/artifactory/datasource/repository"
rs "github.com/jfrog/terraform-provider-artifactory/v10/pkg/artifactory/resource"
"github.com/jfrog/terraform-provider-artifactory/v10/pkg/artifactory/resource/configuration"
"github.com/jfrog/terraform-provider-artifactory/v10/pkg/artifactory/resource/security"
"github.com/jfrog/terraform-provider-artifactory/v10/pkg/artifactory/resource/user"
Expand Down Expand Up @@ -145,7 +146,7 @@ func (p *ArtifactoryProvider) Configure(ctx context.Context, req provider.Config

version, err := util.GetArtifactoryVersion(restyBase)
if err != nil {
resp.Diagnostics.AddWarning(
resp.Diagnostics.AddError(
"Error getting Artifactory version",
fmt.Sprintf("The provider functionality might be affected by the absence of Artifactory version in the context. %v", err),
)
Expand All @@ -155,22 +156,20 @@ func (p *ArtifactoryProvider) Configure(ctx context.Context, req provider.Config
featureUsage := fmt.Sprintf("Terraform/%s", req.TerraformVersion)
go util.SendUsage(ctx, restyBase, productId, featureUsage)

resp.DataSourceData = util.ProvderMetadata{
meta := util.ProviderMetadata{
Client: restyBase,
ProductId: productId,
ArtifactoryVersion: version,
}

resp.ResourceData = util.ProvderMetadata{
Client: restyBase,
ProductId: productId,
ArtifactoryVersion: version,
}
resp.DataSourceData = meta
resp.ResourceData = meta
}

// Resources satisfies the provider.Provider interface for ArtifactoryProvider.
func (p *ArtifactoryProvider) Resources(ctx context.Context) []func() resource.Resource {
return []func() resource.Resource{
rs.NewArtifactResource,
user.NewUserResource,
user.NewManagedUserResource,
user.NewAnonymousUserResource,
Expand Down
9 changes: 4 additions & 5 deletions pkg/artifactory/provider/sdkv2.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,21 +94,20 @@ func providerConfigure(ctx context.Context, d *schema.ResourceData, terraformVer
// Due to migration from SDK v2 to plugin framework, we have to remove defaults from the provider configuration.
// https://discuss.hashicorp.com/t/muxing-upgraded-tfsdk-and-framework-provider-with-default-provider-configuration/43945
checkLicense := true
v, checkLicenseBoolSet := d.GetOk("check_license")
if checkLicenseBoolSet {
if v, ok := d.GetOk("check_license"); ok {
checkLicense = v.(bool)
}
if checkLicense {
licenseErr := util.CheckArtifactoryLicense(restyBase, "Enterprise", "Commercial", "Edge")
if licenseErr != nil {
return nil, diag.FromErr(err)
return nil, diag.FromErr(licenseErr)
}
}

version, err := util.GetArtifactoryVersion(restyBase)
if err != nil {
return nil, diag.Diagnostics{{
Severity: diag.Warning,
Severity: diag.Error,
Summary: "Error getting Artifactory version",
Detail: fmt.Sprintf("The provider functionality might be affected by the absence of Artifactory version in the context. %v", err),
}}
Expand All @@ -117,7 +116,7 @@ func providerConfigure(ctx context.Context, d *schema.ResourceData, terraformVer
featureUsage := fmt.Sprintf("Terraform/%s", terraformVersion)
util.SendUsage(ctx, restyBase, productId, featureUsage)

return util.ProvderMetadata{
return util.ProviderMetadata{
Client: restyBase,
ArtifactoryVersion: version,
}, nil
Expand Down
2 changes: 1 addition & 1 deletion pkg/artifactory/resource/configuration/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
See https://www.jfrog.com/confluence/display/JFROG/Artifactory+YAML+Configuration
*/
func SendConfigurationPatch(content []byte, m interface{}) error {
resp, err := m.(util.ProvderMetadata).Client.R().SetBody(content).
resp, err := m.(util.ProviderMetadata).Client.R().SetBody(content).
SetHeader("Content-Type", "application/yaml").
AddRetryCondition(client.RetryOnMergeError).
Patch("artifactory/api/system/configuration")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func NewBackupResource() resource.Resource {
}

type BackupResource struct {
ProviderData util.ProvderMetadata
ProviderData util.ProviderMetadata
TypeName string
}

Expand Down Expand Up @@ -195,7 +195,7 @@ func (r *BackupResource) Configure(ctx context.Context, req resource.ConfigureRe
if req.ProviderData == nil {
return
}
r.ProviderData = req.ProviderData.(util.ProvderMetadata)
r.ProviderData = req.ProviderData.(util.ProviderMetadata)
}

func (r *BackupResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ func cronTestCase(cronExpression string, t *testing.T) (*testing.T, resource.Tes

func testAccBackupDestroy(id string) func(*terraform.State) error {
return func(s *terraform.State) error {
client := acctest.Provider.Meta().(util.ProvderMetadata).Client
client := acctest.Provider.Meta().(util.ProviderMetadata).Client

_, ok := s.RootModule().Resources["artifactory_backup."+id]
if !ok {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func ResourceArtifactoryGeneralSecurity() *schema.Resource {
}

func resourceGeneralSecurityRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
c := m.(util.ProvderMetadata).Client
c := m.(util.ProviderMetadata).Client

generalSettings := GeneralSettings{}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func TestAccGeneralSecurity_full(t *testing.T) {

func testAccGeneralSecurityDestroy(id string) func(*terraform.State) error {
return func(s *terraform.State) error {
client := acctest.Provider.Meta().(util.ProvderMetadata).Client
client := acctest.Provider.Meta().(util.ProviderMetadata).Client

_, ok := s.RootModule().Resources[id]
if !ok {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ Hierarchy: The user's DN is indicative of the groups the user belongs to by usin
name := data.GetString("name", false)

ldapGroupConfigs := XmlLdapGroupConfig{}
resp, err := m.(util.ProvderMetadata).Client.R().SetResult(&ldapGroupConfigs).Get("artifactory/api/system/configuration")
resp, err := m.(util.ProviderMetadata).Client.R().SetResult(&ldapGroupConfigs).Get("artifactory/api/system/configuration")
if err != nil {
return diag.Errorf("failed to retrieve data from API: /artifactory/api/system/configuration during Read")
}
Expand Down Expand Up @@ -167,7 +167,7 @@ Hierarchy: The user's DN is indicative of the groups the user belongs to by usin

rsrcLdapGroupSetting := unpackLdapGroupSetting(d)

response, err := m.(util.ProvderMetadata).Client.R().SetResult(&ldapGroupConfigs).Get("artifactory/api/system/configuration")
response, err := m.(util.ProviderMetadata).Client.R().SetResult(&ldapGroupConfigs).Get("artifactory/api/system/configuration")
if err != nil {
return diag.Errorf("failed to retrieve data from API: /artifactory/api/system/configuration during Read")
}
Expand Down
Loading

0 comments on commit 9f83e9c

Please sign in to comment.