Skip to content

Commit d4d27de

Browse files
feat(CENG-689) Add generic upstream support (#164)
* add generic upstream support * deb test fix
1 parent 8f51679 commit d4d27de

File tree

6 files changed

+187
-5
lines changed

6 files changed

+187
-5
lines changed

cloudsmith/resource_repository_upstream.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const (
2121
Dart = "dart"
2222
Deb = "deb"
2323
Docker = "docker"
24+
Generic = "generic"
2425
Go = "go"
2526
Helm = "helm"
2627
Hex = "hex"
@@ -51,6 +52,7 @@ const (
5152
Mode = "mode"
5253
Priority = "priority"
5354
UpstreamDistribution = "upstream_distribution"
55+
UpstreamPrefix = "upstream_prefix"
5456
UpstreamType = "upstream_type"
5557
UpstreamUrl = "upstream_url"
5658
VerifySsl = "verify_ssl"
@@ -78,6 +80,7 @@ var (
7880
Dart,
7981
Deb,
8082
Docker,
83+
Generic,
8184
Go,
8285
Helm,
8386
Hex,
@@ -341,6 +344,25 @@ func resourceRepositoryUpstreamCreate(d *schema.ResourceData, m interface{}) err
341344
}
342345
return execErr
343346
}
347+
case Generic:
348+
req := pc.APIClient.ReposApi.ReposUpstreamGenericCreate(pc.Auth, namespace, repository)
349+
req = req.Data(cloudsmith.GenericUpstreamRequest{
350+
AuthMode: authMode,
351+
AuthSecret: authSecret,
352+
AuthUsername: authUsername,
353+
ExtraHeader1: extraHeader1,
354+
ExtraHeader2: extraHeader2,
355+
ExtraValue1: extraValue1,
356+
ExtraValue2: extraValue2,
357+
IsActive: isActive,
358+
Mode: mode,
359+
Name: name,
360+
Priority: priority,
361+
UpstreamPrefix: optionalString(d, UpstreamPrefix),
362+
UpstreamUrl: upstreamUrl,
363+
VerifySsl: verifySsl,
364+
})
365+
upstream, resp, err = pc.APIClient.ReposApi.ReposUpstreamGenericCreateExecute(req)
344366
case Go:
345367
req := pc.APIClient.ReposApi.ReposUpstreamGoCreate(pc.Auth, namespace, repository)
346368
req = req.Data(cloudsmith.GoUpstreamRequest{
@@ -604,6 +626,9 @@ func getUpstream(d *schema.ResourceData, m interface{}) (Upstream, *http.Respons
604626
case Docker:
605627
req := pc.APIClient.ReposApi.ReposUpstreamDockerRead(pc.Auth, namespace, repository, d.Id())
606628
upstream, resp, err = pc.APIClient.ReposApi.ReposUpstreamDockerReadExecute(req)
629+
case Generic:
630+
req := pc.APIClient.ReposApi.ReposUpstreamGenericRead(pc.Auth, namespace, repository, d.Id())
631+
upstream, resp, err = pc.APIClient.ReposApi.ReposUpstreamGenericReadExecute(req)
607632
case Go:
608633
req := pc.APIClient.ReposApi.ReposUpstreamGoRead(pc.Auth, namespace, repository, d.Id())
609634
upstream, resp, err = pc.APIClient.ReposApi.ReposUpstreamGoReadExecute(req)
@@ -690,6 +715,8 @@ func resourceRepositoryUpstreamRead(d *schema.ResourceData, m interface{}) error
690715
_ = d.Set(DistroVersions, flattenStrings(u.GetDistroVersions()))
691716
_ = d.Set(IncludeSources, u.GetIncludeSources())
692717
_ = d.Set(UpstreamDistribution, u.GetUpstreamDistribution())
718+
case *cloudsmith.GenericUpstream:
719+
_ = d.Set(UpstreamPrefix, u.GetUpstreamPrefix())
693720
case *cloudsmith.RpmUpstream:
694721
_ = d.Set(DistroVersion, u.GetDistroVersion())
695722
_ = d.Set(IncludeSources, u.GetIncludeSources())
@@ -874,6 +901,25 @@ func resourceRepositoryUpstreamUpdate(d *schema.ResourceData, m interface{}) err
874901
if execErr != nil {
875902
return execErr
876903
}
904+
case Generic:
905+
req := pc.APIClient.ReposApi.ReposUpstreamGenericUpdate(pc.Auth, namespace, repository, slugPerm)
906+
req = req.Data(cloudsmith.GenericUpstreamRequest{
907+
AuthMode: authMode,
908+
AuthSecret: authSecret,
909+
AuthUsername: authUsername,
910+
ExtraHeader1: extraHeader1,
911+
ExtraHeader2: extraHeader2,
912+
ExtraValue1: extraValue1,
913+
ExtraValue2: extraValue2,
914+
IsActive: isActive,
915+
Mode: mode,
916+
Name: name,
917+
Priority: priority,
918+
UpstreamPrefix: optionalString(d, UpstreamPrefix),
919+
UpstreamUrl: upstreamUrl,
920+
VerifySsl: verifySsl,
921+
})
922+
upstream, _, err = pc.APIClient.ReposApi.ReposUpstreamGenericUpdateExecute(req)
877923
case Go:
878924
req := pc.APIClient.ReposApi.ReposUpstreamGoUpdate(pc.Auth, namespace, repository, slugPerm)
879925
req = req.Data(cloudsmith.GoUpstreamRequest{
@@ -1131,6 +1177,9 @@ func resourceRepositoryUpstreamDelete(d *schema.ResourceData, m interface{}) err
11311177
case Docker:
11321178
req := pc.APIClient.ReposApi.ReposUpstreamDockerDelete(pc.Auth, namespace, repository, d.Id())
11331179
_, err = pc.APIClient.ReposApi.ReposUpstreamDockerDeleteExecute(req)
1180+
case Generic:
1181+
req := pc.APIClient.ReposApi.ReposUpstreamGenericDelete(pc.Auth, namespace, repository, d.Id())
1182+
_, err = pc.APIClient.ReposApi.ReposUpstreamGenericDeleteExecute(req)
11341183
case Go:
11351184
req := pc.APIClient.ReposApi.ReposUpstreamGoDelete(pc.Auth, namespace, repository, d.Id())
11361185
_, err = pc.APIClient.ReposApi.ReposUpstreamGoDeleteExecute(req)
@@ -1357,6 +1406,12 @@ func resourceRepositoryUpstream() *schema.Resource {
13571406
Optional: true,
13581407
ValidateFunc: validation.StringIsNotEmpty,
13591408
},
1409+
UpstreamPrefix: {
1410+
Type: schema.TypeString,
1411+
Description: "(generic only) A unique prefix used to distinguish this upstream source within the repository. Requests including this prefix are routed to this upstream.",
1412+
Optional: true,
1413+
Computed: true,
1414+
},
13601415
UpstreamType: {
13611416
Type: schema.TypeString,
13621417
Description: "The type of Upstream (docker, nuget, python, ...)",

cloudsmith/resource_repository_upstream_test.go

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ resource "cloudsmith_repository_upstream" "ubuntu" {
333333
namespace = cloudsmith_repository.test.namespace
334334
repository = cloudsmith_repository.test.slug
335335
name = cloudsmith_repository.test.name
336+
upstream_distribution = "xenial"
336337
upstream_type = "deb"
337338
upstream_url = "http://archive.ubuntu.com/ubuntu"
338339
}
@@ -389,7 +390,7 @@ resource "cloudsmith_repository_upstream" "ubuntu" {
389390
resource.TestCheckResourceAttrSet(debUpstreamResourceName, Priority),
390391
resource.TestCheckResourceAttrSet(debUpstreamResourceName, SlugPerm),
391392
resource.TestCheckResourceAttrSet(debUpstreamResourceName, UpdatedAt),
392-
resource.TestCheckResourceAttr(debUpstreamResourceName, UpstreamDistribution, ""),
393+
resource.TestCheckResourceAttr(debUpstreamResourceName, UpstreamDistribution, "xenial"),
393394
resource.TestCheckResourceAttr(debUpstreamResourceName, VerifySsl, "true"),
394395
),
395396
},
@@ -646,6 +647,113 @@ resource "cloudsmith_repository_upstream" "fakedocker" {
646647
})
647648
}
648649

650+
func TestAccRepositoryUpstreamGeneric_basic(t *testing.T) {
651+
t.Parallel()
652+
653+
const genericUpstreamResourceName = "cloudsmith_repository_upstream.gradle_distributions"
654+
655+
testAccRepositoryGenericUpstreamConfigBasic := fmt.Sprintf(`
656+
resource "cloudsmith_repository" "test" {
657+
name = "terraform-acc-test-upstream-generic"
658+
namespace = "%s"
659+
}
660+
661+
resource "cloudsmith_repository_upstream" "gradle_distributions" {
662+
namespace = cloudsmith_repository.test.namespace
663+
repository = cloudsmith_repository.test.slug
664+
name = cloudsmith_repository.test.name
665+
upstream_type = "generic"
666+
upstream_url = "https://services.gradle.org"
667+
upstream_prefix = "distributions"
668+
}
669+
`, namespace)
670+
671+
testAccRepositoryGenericUpstreamConfigUpdate := fmt.Sprintf(`
672+
resource "cloudsmith_repository" "test" {
673+
name = "terraform-acc-test-upstream-generic"
674+
namespace = "%s"
675+
}
676+
677+
resource "cloudsmith_repository_upstream" "gradle_distributions" {
678+
extra_header_1 = "X-Custom-Header"
679+
extra_header_2 = "Access-Control-Allow-Origin"
680+
extra_value_1 = "custom-value"
681+
extra_value_2 = "*"
682+
is_active = true
683+
mode = "Proxy Only"
684+
name = cloudsmith_repository.test.name
685+
namespace = cloudsmith_repository.test.namespace
686+
priority = 12345
687+
repository = cloudsmith_repository.test.slug
688+
upstream_type = "generic"
689+
upstream_url = "https://services.gradle.org"
690+
upstream_prefix = "distributions"
691+
verify_ssl = false
692+
}
693+
`, namespace)
694+
695+
resource.Test(t, resource.TestCase{
696+
PreCheck: func() { testAccPreCheck(t) },
697+
Providers: testAccProviders,
698+
CheckDestroy: testAccRepositoryUpstreamCheckDestroy(genericUpstreamResourceName),
699+
Steps: []resource.TestStep{
700+
{
701+
Config: testAccRepositoryGenericUpstreamConfigBasic,
702+
Check: resource.ComposeTestCheckFunc(
703+
resource.TestCheckResourceAttr(genericUpstreamResourceName, AuthMode, "None"),
704+
resource.TestCheckResourceAttr(genericUpstreamResourceName, AuthUsername, ""),
705+
resource.TestCheckNoResourceAttr(genericUpstreamResourceName, Component),
706+
resource.TestCheckResourceAttrSet(genericUpstreamResourceName, CreatedAt),
707+
resource.TestCheckNoResourceAttr(genericUpstreamResourceName, DistroVersion),
708+
resource.TestCheckNoResourceAttr(genericUpstreamResourceName, DistroVersions),
709+
resource.TestCheckResourceAttr(genericUpstreamResourceName, ExtraHeader1, ""),
710+
resource.TestCheckResourceAttr(genericUpstreamResourceName, ExtraHeader2, ""),
711+
resource.TestCheckResourceAttr(genericUpstreamResourceName, ExtraValue1, ""),
712+
resource.TestCheckResourceAttr(genericUpstreamResourceName, ExtraValue2, ""),
713+
resource.TestCheckNoResourceAttr(genericUpstreamResourceName, IncludeSources),
714+
resource.TestCheckResourceAttr(genericUpstreamResourceName, IsActive, "true"),
715+
resource.TestCheckResourceAttr(genericUpstreamResourceName, Mode, "Proxy Only"),
716+
resource.TestCheckResourceAttrSet(genericUpstreamResourceName, Priority),
717+
resource.TestCheckResourceAttrSet(genericUpstreamResourceName, SlugPerm),
718+
resource.TestCheckResourceAttrSet(genericUpstreamResourceName, UpdatedAt),
719+
resource.TestCheckNoResourceAttr(genericUpstreamResourceName, UpstreamDistribution),
720+
resource.TestCheckResourceAttr(genericUpstreamResourceName, "upstream_prefix", "distributions"),
721+
resource.TestCheckResourceAttr(genericUpstreamResourceName, VerifySsl, "true"),
722+
),
723+
},
724+
{
725+
Config: testAccRepositoryGenericUpstreamConfigUpdate,
726+
Check: resource.ComposeTestCheckFunc(
727+
resource.TestCheckNoResourceAttr(genericUpstreamResourceName, Component),
728+
resource.TestCheckResourceAttrSet(genericUpstreamResourceName, CreatedAt),
729+
resource.TestCheckNoResourceAttr(genericUpstreamResourceName, DistroVersion),
730+
resource.TestCheckNoResourceAttr(genericUpstreamResourceName, DistroVersions),
731+
resource.TestCheckNoResourceAttr(genericUpstreamResourceName, IncludeSources),
732+
resource.TestCheckResourceAttrSet(genericUpstreamResourceName, UpdatedAt),
733+
resource.TestCheckNoResourceAttr(genericUpstreamResourceName, UpstreamDistribution),
734+
resource.TestCheckResourceAttr(genericUpstreamResourceName, IsActive, "true"),
735+
resource.TestCheckResourceAttr(genericUpstreamResourceName, "upstream_prefix", "distributions"),
736+
),
737+
},
738+
{
739+
ResourceName: genericUpstreamResourceName,
740+
ImportState: true,
741+
ImportStateIdFunc: func(s *terraform.State) (string, error) {
742+
resourceState := s.RootModule().Resources[genericUpstreamResourceName]
743+
return fmt.Sprintf(
744+
"%s.%s.%s.%s",
745+
resourceState.Primary.Attributes[Namespace],
746+
resourceState.Primary.Attributes[Repository],
747+
resourceState.Primary.Attributes[UpstreamType],
748+
resourceState.Primary.Attributes[SlugPerm],
749+
), nil
750+
},
751+
ImportStateVerify: true,
752+
},
753+
},
754+
})
755+
}
756+
649757
func TestAccRepositoryUpstreamGo_basic(t *testing.T) {
650758
t.Parallel()
651759

@@ -1827,6 +1935,9 @@ func testAccRepositoryUpstreamCheckDestroy(resourceName string) resource.TestChe
18271935
case Docker:
18281936
req := pc.APIClient.ReposApi.ReposUpstreamDockerRead(pc.Auth, namespace, repository, slugPerm)
18291937
_, resp, err = pc.APIClient.ReposApi.ReposUpstreamDockerReadExecute(req)
1938+
case Generic:
1939+
req := pc.APIClient.ReposApi.ReposUpstreamGenericRead(pc.Auth, namespace, repository, slugPerm)
1940+
_, resp, err = pc.APIClient.ReposApi.ReposUpstreamGenericReadExecute(req)
18301941
case Go:
18311942
req := pc.APIClient.ReposApi.ReposUpstreamGoRead(pc.Auth, namespace, repository, slugPerm)
18321943
_, resp, err = pc.APIClient.ReposApi.ReposUpstreamGoReadExecute(req)

cloudsmith/resource_team.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func resourceTeamCreate(d *schema.ResourceData, m interface{}) error {
3333

3434
req := pc.APIClient.OrgsApi.OrgsTeamsCreate(pc.Auth, org)
3535
req = req.Data(cloudsmith.OrganizationTeamRequest{
36-
Description: optionalString(d, "description"),
36+
Description: nullableString(d, "description"),
3737
Name: requiredString(d, "name"),
3838
Slug: optionalString(d, "slug"),
3939
Visibility: optionalString(d, "visibility"),
@@ -127,7 +127,7 @@ func resourceTeamUpdate(d *schema.ResourceData, m interface{}) error {
127127

128128
req := pc.APIClient.OrgsApi.OrgsTeamsPartialUpdate(pc.Auth, org, d.Id())
129129
req = req.Data(cloudsmith.OrganizationTeamRequestPatch{
130-
Description: optionalString(d, "description"),
130+
Description: nullableString(d, "description"),
131131
Name: optionalString(d, "name"),
132132
Slug: optionalString(d, "slug"),
133133
Visibility: optionalString(d, "visibility"),

docs/resources/repository_upstream.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,19 @@ resource "cloudsmith_repository_upstream" "other_docker_upstream" {
135135
}
136136
```
137137

138+
### Generic
139+
140+
```hcl
141+
resource "cloudsmith_repository_upstream" "gradle_distributions" {
142+
name = "Gradle Distributions"
143+
namespace = "${data.cloudsmith_organization.my_organization.slug_perm}"
144+
repository = "${resource.cloudsmith_repository.my_repository.slug_perm}"
145+
upstream_type = "generic"
146+
upstream_url = "https://services.gradle.org"
147+
upstream_prefix = "distributions"
148+
}
149+
```
150+
138151
### Go
139152

140153
```hcl
@@ -295,7 +308,8 @@ The following arguments are supported:
295308
| `priority` | N | number | N/A | Upstream sources are selected for resolving requests by sequential order (1..n), followed by creation date. |
296309
| `repository` | Y | string | N/A | The Repository to which the upstream belongs. |
297310
| `upstream_distribution` | N | string | N/A | Used only in conjunction with an `upstream_type` of `"deb"` to declare the [distribution](https://wiki.debian.org/DebianRepository/Format#Overview) to fetch from the upstream. |
298-
| `upstream_type` | Y | string | `"cargo"`<br>`"composer"`<br>`"conda"`<br>`"cran"`<br>`"dart"`<br>`"deb"`<br>`"docker"`<br>`"go"`<br>`"helm"`<br>`"hex"`<br>`"huggingface"`<br>`"maven"`<br>`"npm"`<br>`"nuget"`<br>`"python"`<br>`"rpm"`<br>`"ruby"`<br>`"swift"` | The type of Upstream. |
311+
| `upstream_prefix` | N | string | N/A | Used only in conjunction with an `upstream_type` of `"generic"` to declare a unique prefix to distinguish this upstream source. Requests including this prefix are routed to this upstream. |
312+
| `upstream_type` | Y | string | `"cargo"`<br>`"composer"`<br>`"conda"`<br>`"cran"`<br>`"dart"`<br>`"deb"`<br>`"docker"`<br>`"generic"`<br>`"go"`<br>`"helm"`<br>`"hex"`<br>`"huggingface"`<br>`"maven"`<br>`"npm"`<br>`"nuget"`<br>`"python"`<br>`"rpm"`<br>`"ruby"`<br>`"swift"` | The type of Upstream. |
299313
| `upstream_url` | Y | string | N/A | The URL for this upstream source. This must be a fully qualified URL including any path elements required to reach the root of the repository. The URL cannot end with a trailing slash. |
300314
| `verify_ssl` | N | bool | N/A | If enabled, SSL certificates are verified when requests are made to this upstream. It's recommended to leave this enabled for all public sources to help mitigate Man-In-The-Middle (MITM) attacks. Please note this only applies to HTTPS upstreams. |
301315

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/cloudsmith-io/terraform-provider-cloudsmith
33
go 1.19
44

55
require (
6-
github.com/cloudsmith-io/cloudsmith-api-go v0.0.50
6+
github.com/cloudsmith-io/cloudsmith-api-go v0.0.54
77
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320
88
github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.1
99
github.com/samber/lo v1.36.0

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ github.com/cloudsmith-io/cloudsmith-api-go v0.0.49 h1:L9zUEtpF5BJd/3UHkheU1sFEm/
3333
github.com/cloudsmith-io/cloudsmith-api-go v0.0.49/go.mod h1:xHTDgU8TyMXiWUZdn2OQR7AaZdz9M5SrNenyQU44zGQ=
3434
github.com/cloudsmith-io/cloudsmith-api-go v0.0.50 h1:wXOwzDvrMPNV6c7LNvO6cLOuphKH08/0gCmf8XFtblE=
3535
github.com/cloudsmith-io/cloudsmith-api-go v0.0.50/go.mod h1:xHTDgU8TyMXiWUZdn2OQR7AaZdz9M5SrNenyQU44zGQ=
36+
github.com/cloudsmith-io/cloudsmith-api-go v0.0.54 h1:CLhFbIQYaCwa3p5XjRTpw/Fu5ZcPpOhT4FCFQovaacI=
37+
github.com/cloudsmith-io/cloudsmith-api-go v0.0.54/go.mod h1:xHTDgU8TyMXiWUZdn2OQR7AaZdz9M5SrNenyQU44zGQ=
3638
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
3739
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3840
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=

0 commit comments

Comments
 (0)