Skip to content

Commit

Permalink
Merge pull request #337 from Guent4/AddReplicationProxySupport
Browse files Browse the repository at this point in the history
Fixes #336 Add capability to specify proxy for Artifactory repository replications
  • Loading branch information
maheshjfrog authored Mar 8, 2022
2 parents 3ce8351 + d916c48 commit 13cd418
Show file tree
Hide file tree
Showing 13 changed files with 192 additions and 104 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## 2.22.0 (Mar 8, 2022)

FEATURES:

* resource/artifactory_push_replication: Add support for specifying proxy. [GH-337]
* resource/artifactory_replication_config: Add support for specifying proxy. [GH-337]
* resource/artifactory_single_replication: Add support for specifying proxy. [GH-337]

## 2.21.0 (Mar 3, 2022)

FEATURES:
Expand Down
1 change: 1 addition & 0 deletions docs/resources/artifactory_push_replication.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ The following arguments are supported:
* `sync_properties` - (Optional)
* `sync_statistics` - (Optional)
* `path_prefix` - (Optional)
* `proxy` - (Optional) Proxy key from Artifactory Proxies setting

## Import

Expand Down
1 change: 1 addition & 0 deletions docs/resources/artifactory_replication_config.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ The following arguments are supported:
* `sync_properties` - (Optional)
* `sync_statistics` - (Optional)
* `path_prefix` - (Optional)
* `proxy` - (Optional) Proxy key from Artifactory Proxies setting

## Import

Expand Down
1 change: 1 addition & 0 deletions docs/resources/artifactory_single_replication_config.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ The following arguments are supported:
* `sync_properties` - (Optional)
* `sync_statistics` - (Optional)
* `path_prefix` - (Optional)
* `proxy` - (Optional) Proxy key from Artifactory Proxies setting

## Import

Expand Down
5 changes: 2 additions & 3 deletions pkg/artifactory/resource_artifactory_pull_replication.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (

"github.com/go-resty/resty/v2"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/jfrog/jfrog-client-go/artifactory/services/utils"
)

func resourceArtifactoryPullReplication() *schema.Resource {
Expand All @@ -27,9 +26,9 @@ func resourceArtifactoryPullReplication() *schema.Resource {
}
}

func unpackPullReplication(s *schema.ResourceData) *utils.ReplicationBody {
func unpackPullReplication(s *schema.ResourceData) *ReplicationBody {
d := &ResourceData{s}
replicationConfig := new(utils.ReplicationBody)
replicationConfig := new(ReplicationBody)

replicationConfig.RepoKey = d.getString("repo_key", false)
replicationConfig.CronExp = d.getString("cron_exp", false)
Expand Down
65 changes: 53 additions & 12 deletions pkg/artifactory/resource_artifactory_push_replication.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,53 @@ package artifactory

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"

"github.com/go-resty/resty/v2"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/jfrog/jfrog-client-go/artifactory/services/utils"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)

type PushReplication struct {
type ReplicationBody struct {
Username string `json:"username"`
Password string `json:"password"`
URL string `json:"url"`
CronExp string `json:"cronExp"`
RepoKey string `json:"repoKey"`
EnableEventReplication bool `json:"enableEventReplication"`
SocketTimeoutMillis int `json:"socketTimeoutMillis"`
Enabled bool `json:"enabled"`
SyncDeletes bool `json:"syncDeletes"`
SyncProperties bool `json:"syncProperties"`
SyncStatistics bool `json:"syncStatistics"`
PathPrefix string `json:"pathPrefix"`
}

type getReplicationBody struct {
ReplicationBody
ProxyRef string `json:"proxyRef"`
}

type updateReplicationBody struct {
ReplicationBody
Proxy string `json:"proxy"`
}

type GetPushReplication struct {
RepoKey string `json:"-"`
CronExp string `json:"cronExp,omitempty"`
EnableEventReplication bool `json:"enableEventReplication,omitempty"`
Replications []getReplicationBody `json:"replications,omitempty"`
}

type UpdatePushReplication struct {
RepoKey string `json:"-"`
CronExp string `json:"cronExp,omitempty"`
EnableEventReplication bool `json:"enableEventReplication,omitempty"`
Replications []utils.ReplicationBody `json:"replications,omitempty"`
Replications []updateReplicationBody `json:"replications,omitempty"`
}

var pushReplicationSchemaCommon = map[string]*schema.Schema{
Expand Down Expand Up @@ -95,6 +126,11 @@ var pushReplicationSchema = map[string]*schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"proxy": {
Type: schema.TypeString,
Optional: true,
Description: "Proxy key from Artifactory Proxies setting",
},
}

func resourceArtifactoryPushReplication() *schema.Resource {
Expand All @@ -112,16 +148,16 @@ func resourceArtifactoryPushReplication() *schema.Resource {
}
}

func unpackPushReplication(s *schema.ResourceData) PushReplication {
func unpackPushReplication(s *schema.ResourceData) UpdatePushReplication {
d := &ResourceData{s}
pushReplication := new(PushReplication)
pushReplication := new(UpdatePushReplication)

repo := d.getString("repo_key", false)

if v, ok := d.GetOk("replications"); ok {
arr := v.([]interface{})

tmp := make([]utils.ReplicationBody, 0, len(arr))
tmp := make([]updateReplicationBody, 0, len(arr))
pushReplication.Replications = tmp

for i, o := range arr {
Expand All @@ -133,7 +169,7 @@ func unpackPushReplication(s *schema.ResourceData) PushReplication {

m := o.(map[string]interface{})

var replication utils.ReplicationBody
var replication updateReplicationBody

replication.RepoKey = repo

Expand Down Expand Up @@ -169,6 +205,10 @@ func unpackPushReplication(s *schema.ResourceData) PushReplication {
replication.PathPrefix = prefix.(string)
}

if _, ok := m["proxy"]; ok {
replication.Proxy = handleResetWithNonExistantValue(d, fmt.Sprintf("replications.%d.proxy", i))
}

if pass, ok := m["password"]; ok {
replication.Password = pass.(string)
}
Expand All @@ -180,7 +220,7 @@ func unpackPushReplication(s *schema.ResourceData) PushReplication {
return *pushReplication
}

func packPushReplication(pushReplication *PushReplication, d *schema.ResourceData) diag.Diagnostics {
func packPushReplication(pushReplication *GetPushReplication, d *schema.ResourceData) diag.Diagnostics {
var errors []error
setValue := mkLens(d)

Expand All @@ -202,6 +242,7 @@ func packPushReplication(pushReplication *PushReplication, d *schema.ResourceDat
replication["sync_properties"] = repo.SyncProperties
replication["sync_statistics"] = repo.SyncStatistics
replication["path_prefix"] = repo.PathPrefix
replication["proxy"] = repo.ProxyRef
replications = append(replications, replication)
}

Expand All @@ -228,14 +269,14 @@ func resourcePushReplicationCreate(ctx context.Context, d *schema.ResourceData,

func resourcePushReplicationRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
c := m.(*resty.Client)
var replications []utils.ReplicationBody
var replications []getReplicationBody
_, err := c.R().SetResult(&replications).Get("artifactory/api/replications/" + d.Id())

if err != nil {
return diag.FromErr(err)
}

repConfig := PushReplication{
repConfig := GetPushReplication{
RepoKey: d.Id(),
Replications: replications,
}
Expand Down
13 changes: 11 additions & 2 deletions pkg/artifactory/resource_artifactory_push_replication_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ func TestInvalidPushReplicationUrlFails(t *testing.T) {
}

func TestAccPushReplication_full(t *testing.T) {
const testProxy = "test-proxy"
const replicationConfigTemplate = `
resource "artifactory_local_repository" "lib-local" {
key = "lib-local"
Expand All @@ -84,12 +85,19 @@ func TestAccPushReplication_full(t *testing.T) {
replications {
url = "%s"
username = "%s"
proxy = "%s"
}
}
`

resource.Test(t, resource.TestCase{
CheckDestroy: testAccCheckPushReplicationDestroy("artifactory_push_replication.lib-local"),
PreCheck: func() {
createProxy(t, testProxy)
},
CheckDestroy: func() func(*terraform.State) error {
deleteProxy(t, testProxy)
return testAccCheckPushReplicationDestroy("artifactory_push_replication.lib-local")
}(),
ProviderFactories: testAccProviders,

Steps: []resource.TestStep{
Expand All @@ -98,12 +106,14 @@ func TestAccPushReplication_full(t *testing.T) {
replicationConfigTemplate,
os.Getenv("ARTIFACTORY_URL"),
os.Getenv("ARTIFACTORY_USERNAME"),
testProxy,
),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("artifactory_push_replication.lib-local", "repo_key", "lib-local"),
resource.TestCheckResourceAttr("artifactory_push_replication.lib-local", "cron_exp", "0 0 * * * ?"),
resource.TestCheckResourceAttr("artifactory_push_replication.lib-local", "enable_event_replication", "true"),
resource.TestCheckResourceAttr("artifactory_push_replication.lib-local", "replications.#", "1"),
resource.TestCheckResourceAttr("artifactory_push_replication.lib-local", "replications.0.proxy", testProxy),
),
},
},
Expand All @@ -112,7 +122,6 @@ func TestAccPushReplication_full(t *testing.T) {

func testAccCheckPushReplicationDestroy(id string) func(*terraform.State) error {
return func(s *terraform.State) error {

rs, ok := s.RootModule().Resources[id]
if !ok {
return fmt.Errorf("err: Resource id[%s] not found", id)
Expand Down
47 changes: 0 additions & 47 deletions pkg/artifactory/resource_artifactory_remote_repository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (

"github.com/go-resty/resty/v2"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"gopkg.in/yaml.v2"
)

func TestAccLocalAllowDotsUnderscorersAndDashesInKeyGH129(t *testing.T) {
Expand Down Expand Up @@ -681,52 +680,6 @@ func TestAccRemoteProxyUpdateGH2(t *testing.T) {
}
`, name, key)

type Proxy struct {
Key string `yaml:"key"`
Host string `yaml:"host"`
Port int `yaml:"port"`
PlatformDefault bool `yaml:"platformDefault"`
}

var updateProxiesConfig = func(t *testing.T, proxyKey string, getProxiesBody func() []byte) {
body := getProxiesBody()
restyClient := getTestResty(t)

err := sendConfigurationPatch(body, restyClient)
if err != nil {
t.Fatal(err)
}
}

var createProxy = func(t *testing.T, proxyKey string) {
updateProxiesConfig(t, proxyKey, func() []byte {
testProxy := Proxy{
Key: proxyKey,
Host: "http://fake-proxy.org",
Port: 8080,
PlatformDefault: false,
}

constructBody := map[string][]Proxy{
"proxies": {testProxy},
}

body, err := yaml.Marshal(&constructBody)
if err != nil {
t.Errorf("failed to marshal proxies settings during Update")
}

return body
})
}

var deleteProxy = func(t *testing.T, proxyKey string) {
updateProxiesConfig(t, proxyKey, func() []byte {
// Return empty yaml to clean up all proxies
return []byte(`proxies: ~`)
})
}

testProxyKey := "test-proxy"

resource.Test(t, resource.TestCase{
Expand Down
Loading

0 comments on commit 13cd418

Please sign in to comment.