Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MyJFrog IP allowlist resource #50

Merged
merged 12 commits into from
Apr 9, 2024
6 changes: 6 additions & 0 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ archives:
- format: zip
name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}'
checksum:
extra_files:
- glob: 'terraform-registry-manifest.json'
name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json'
name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS'
algorithm: sha256
signs:
Expand All @@ -48,6 +51,9 @@ signs:
- "--detach-sign"
- "${artifact}"
release:
extra_files:
- glob: 'terraform-registry-manifest.json'
name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json'
# If you want to manually examine the release before its live, uncomment this line:
# draft: true
changelog:
Expand Down
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
## 1.6.0 (Apr 5, 2024)

FEATURES:

* **New Resource:** `platform_myjfrog_ip_allowlist`: Resource to manage MyJFrog IP allowlist. PR: [#50](https://github.com/jfrog/terraform-provider-platform/pull/50) Issue: [#27](https://github.com/jfrog/terraform-provider-platform/issues/27)

## 1.5.1 (Apr 3, 2024)

BUG FIXES:

* resource/platform_permission: Update documentation for target `name` attribute for `ANY` repository types. Correct values should be `ANY LOCAL`, `ANY REMOTE`, or `ANY DISTRIBUTION`. Note the removal of underscore character. Issue: [#48](https://github.com/jfrog/terraform-provider-platform/issues/48) PR: [#49](https://github.com/jfrog/terraform-provider-platform/pull/49)


## 1.5.0 (Mar 26, 2024)

FEATURES:
Expand Down
5 changes: 3 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ provider "platform" {

### Optional

- `access_token` (String, Sensitive) This is a access token that can be given to you by your admin under `Platform Configuration -> User Management -> Access Tokens`.
- `access_token` (String, Sensitive) This is a access token that can be given to you by your admin under `Platform Configuration -> User Management -> Access Tokens`. This can also be sourced from the `JFROG_ACCESS_TOKEN` environment variable.
- `check_license` (Boolean) Toggle for pre-flight checking of Artifactory Pro and Enterprise license. Default to `true`.
- `url` (String) JFrog Platform URL.
- `myjfrog_api_token` (String, Sensitive) MyJFrog API token that allows you to make changes to your JFrog account. See [Generate a Token in MyJFrog](https://jfrog.com/help/r/jfrog-hosting-models-documentation/generate-a-token-in-myjfrog) for more details. This can also be sourced from the `JFROG_MYJFROG_API_TOKEN` environment variable.
- `url` (String) JFrog Platform URL. This can also be sourced from the `JFROG_URL` environment variable.
45 changes: 45 additions & 0 deletions docs/resources/myjfrog_ip_allowlist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "platform_myjfrog_ip_allowlist Resource - terraform-provider-platform"
subcategory: ""
description: |-
Provides a MyJFrog IP allowlist https://jfrog.com/help/r/jfrog-hosting-models-documentation/configure-the-ip/cidr-allowlist resource to manage list of allow IP/CIDR addresses. To use this resource, you need an access token. Only a Primary Admin can generate MyJFrog tokens. For more information, see Generate a Token in MyJFrog https://jfrog.com/help/r/jfrog-hosting-models-documentation/generate-a-token-in-myjfrog.
->This resource is supported only on the Cloud (SaaS) platform.
~>The rate limit is 5 times per hour for actions that result in a successful outcome (for Create, Update, and Delete actions). See Allowlist REST API https://jfrog.com/help/r/jfrog-rest-apis/allowlist-rest-api for full list of limitations.
---

# platform_myjfrog_ip_allowlist (Resource)

Provides a MyJFrog [IP allowlist](https://jfrog.com/help/r/jfrog-hosting-models-documentation/configure-the-ip/cidr-allowlist) resource to manage list of allow IP/CIDR addresses. To use this resource, you need an access token. Only a Primary Admin can generate MyJFrog tokens. For more information, see [Generate a Token in MyJFrog](https://jfrog.com/help/r/jfrog-hosting-models-documentation/generate-a-token-in-myjfrog).

->This resource is supported only on the Cloud (SaaS) platform.

~>The rate limit is **5 times per hour** for actions that result in a successful outcome (for Create, Update, and Delete actions). See [Allowlist REST API](https://jfrog.com/help/r/jfrog-rest-apis/allowlist-rest-api) for full list of limitations.

## Example Usage

```terraform
resource "platform_myjfrog_ip_allowlist" "myjfrog-ip-allowlist" {
server_name = "my-jpd-server-name"
ips = [
"1.1.1.7/1",
"2.2.2.7/1",
]
}
```

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

### Required

- `ips` (Set of String) List of IPs for the JPD allowlist
- `server_name` (String) Name of the server. If your JFrog URL is `myserver.jfrog.io`, the `server_name` is `myserver`.

## Import

Import is supported using the following syntax:

```shell
terraform import platform_myjfrog_ip_allowlist.myjfrog-ip-allowlist jpd-server-name
```
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
terraform import platform_myjfrog_ip_allowlist.myjfrog-ip-allowlist jpd-server-name
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
resource "platform_myjfrog_ip_allowlist" "myjfrog-ip-allowlist" {
server_name = "my-jpd-server-name"
ips = [
"1.1.1.7/1",
"2.2.2.7/1",
]
}
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ require (
github.com/hashicorp/terraform-plugin-framework-validators v0.12.0
github.com/hashicorp/terraform-plugin-go v0.22.1
github.com/hashicorp/terraform-plugin-testing v1.7.0
github.com/jfrog/terraform-provider-shared v1.22.1
github.com/jfrog/terraform-provider-shared v1.22.4
github.com/samber/lo v1.39.0
)

Expand Down Expand Up @@ -47,7 +47,7 @@ require (
github.com/hashicorp/logutils v1.0.0 // indirect
github.com/hashicorp/terraform-exec v0.20.0 // indirect
github.com/hashicorp/terraform-json v0.21.0 // indirect
github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect
github.com/hashicorp/terraform-plugin-log v0.9.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0 // indirect
github.com/hashicorp/terraform-registry-address v0.2.3 // indirect
github.com/hashicorp/terraform-svchost v0.1.1 // indirect
Expand All @@ -65,6 +65,7 @@ require (
github.com/oklog/run v1.0.0 // indirect
github.com/posener/complete v1.2.3 // indirect
github.com/russross/blackfriday v1.6.0 // indirect
github.com/sethvargo/go-retry v0.2.4
github.com/shopspring/decimal v1.3.1 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,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.1 h1:tGety2oaxUiMB4yrpJ9S+770tDxSIlnD4qpL0y9p+z0=
github.com/jfrog/terraform-provider-shared v1.22.1/go.mod h1:OozwvfahZU4Q9u3kXdpQI3h/Etrs2DXoouQDrpxB1cQ=
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/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 Expand Up @@ -178,6 +178,8 @@ github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA=
github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sethvargo/go-retry v0.2.4 h1:T+jHEQy/zKJf5s95UkguisicE0zuF9y7+/vgz08Ocec=
github.com/sethvargo/go-retry v0.2.4/go.mod h1:1afjQuvh7s4gflMObvjLPaWgluLLyhA1wmVZ6KLpICw=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
Expand Down
86 changes: 65 additions & 21 deletions pkg/platform/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"

"github.com/go-resty/resty/v2"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/provider"
Expand All @@ -13,7 +14,6 @@ import (
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/jfrog/terraform-provider-shared/client"
"github.com/jfrog/terraform-provider-shared/util"
utilfw "github.com/jfrog/terraform-provider-shared/util/fw"
validator_string "github.com/jfrog/terraform-provider-shared/validator/fw/string"
)

Expand All @@ -24,14 +24,20 @@ var productId = "terraform-provider-platform/" + Version

var _ provider.Provider = (*PlatformProvider)(nil)

type PlatformProviderMetadata struct {
util.ProvderMetadata
MyJFrogClient *resty.Client
}

type PlatformProvider struct {
Meta util.ProvderMetadata
Meta PlatformProviderMetadata
}

type platformProviderModel struct {
Url types.String `tfsdk:"url"`
AccessToken types.String `tfsdk:"access_token"`
CheckLicense types.Bool `tfsdk:"check_license"`
Url types.String `tfsdk:"url"`
AccessToken types.String `tfsdk:"access_token"`
MyJFrogAPIToken types.String `tfsdk:"myjfrog_api_token"`
CheckLicense types.Bool `tfsdk:"check_license"`
}

func NewProvider() func() provider.Provider {
Expand All @@ -44,6 +50,7 @@ func (p *PlatformProvider) Configure(ctx context.Context, req provider.Configure
// Check environment variables, first available OS variable will be assigned to the var
url := util.CheckEnvVars([]string{"JFROG_URL"}, "")
accessToken := util.CheckEnvVars([]string{"JFROG_ACCESS_TOKEN"}, "")
myJFrogAPIToken := util.CheckEnvVars([]string{"JFROG_MYJFROG_API_TOKEN"}, "")

var config platformProviderModel

Expand All @@ -67,6 +74,10 @@ func (p *PlatformProvider) Configure(ctx context.Context, req provider.Configure
return
}

if config.MyJFrogAPIToken.ValueString() != "" {
myJFrogAPIToken = config.MyJFrogAPIToken.ValueString()
}

if config.Url.ValueString() != "" {
url = config.Url.ValueString()
}
Expand All @@ -79,15 +90,36 @@ func (p *PlatformProvider) Configure(ctx context.Context, req provider.Configure
return
}

restyBase, err := client.Build(url, productId)
var myJFrogClient *resty.Client
if len(myJFrogAPIToken) > 0 {
c, err := client.Build("https://my.jfrog.com", productId)
if err != nil {
resp.Diagnostics.AddError(
"Error creating Resty client for MyJFrog",
err.Error(),
)
}

c, err = client.AddAuth(c, "", myJFrogAPIToken)
if err != nil {
resp.Diagnostics.AddError(
"Error adding Auth to Resty client for MyJFrog",
err.Error(),
)
}

myJFrogClient = c
}

platformClient, err := client.Build(url, productId)
if err != nil {
resp.Diagnostics.AddError(
"Error creating Resty client",
err.Error(),
)
}

restyBase, err = client.AddAuth(restyBase, "", accessToken)
platformClient, err = client.AddAuth(platformClient, "", accessToken)
if err != nil {
resp.Diagnostics.AddError(
"Error adding Auth to Resty client",
Expand All @@ -96,16 +128,16 @@ func (p *PlatformProvider) Configure(ctx context.Context, req provider.Configure
}

if config.CheckLicense.IsNull() || config.CheckLicense.ValueBool() {
if licenseErr := utilfw.CheckArtifactoryLicense(restyBase, "Enterprise", "Commercial", "Edge"); licenseErr != nil {
if licenseErr := util.CheckArtifactoryLicense(platformClient, "Enterprise", "Commercial", "Edge"); licenseErr != nil {
resp.Diagnostics.AddError(
"Error getting Artifactory license",
fmt.Sprintf("%v", licenseErr),
licenseErr.Error(),
)
return
}
}

version, err := util.GetArtifactoryVersion(restyBase)
version, err := util.GetArtifactoryVersion(platformClient)
if err != nil {
resp.Diagnostics.AddWarning(
"Error getting Artifactory version",
Expand All @@ -115,11 +147,14 @@ func (p *PlatformProvider) Configure(ctx context.Context, req provider.Configure
}

featureUsage := fmt.Sprintf("Terraform/%s", req.TerraformVersion)
util.SendUsage(ctx, restyBase, productId, featureUsage)
util.SendUsage(ctx, platformClient, productId, featureUsage)

meta := util.ProvderMetadata{
Client: restyBase,
ArtifactoryVersion: version,
meta := PlatformProviderMetadata{
ProvderMetadata: util.ProvderMetadata{
Client: platformClient,
ArtifactoryVersion: version,
},
MyJFrogClient: myJFrogClient,
}

p.Meta = meta
Expand All @@ -145,6 +180,7 @@ func (p *PlatformProvider) Resources(ctx context.Context) []func() resource.Reso
NewGlobalRoleResource,
NewOIDCConfigurationResource,
NewOIDCIdentityMappingResource,
NewMyJFrogIPAllowListResource,
NewPermissionResource,
NewReverseProxyResource,
NewWorkerServiceResource,
Expand All @@ -155,23 +191,31 @@ func (p *PlatformProvider) Schema(ctx context.Context, req provider.SchemaReques
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"url": schema.StringAttribute{
Description: "JFrog Platform URL.",
Optional: true,
Optional: true,
Validators: []validator.String{
validator_string.IsURLHttpOrHttps(),
},
MarkdownDescription: "JFrog Platform URL. This can also be sourced from the `JFROG_URL` environment variable.",
},
"access_token": schema.StringAttribute{
Description: "This is a access token that can be given to you by your admin under `Platform Configuration -> User Management -> Access Tokens`.",
Optional: true,
Sensitive: true,
Optional: true,
Sensitive: true,
Validators: []validator.String{
stringvalidator.LengthAtLeast(1),
},
MarkdownDescription: "This is a access token that can be given to you by your admin under `Platform Configuration -> User Management -> Access Tokens`. This can also be sourced from the `JFROG_ACCESS_TOKEN` environment variable.",
},
"myjfrog_api_token": schema.StringAttribute{
Optional: true,
Sensitive: true,
Validators: []validator.String{
stringvalidator.LengthAtLeast(1),
},
MarkdownDescription: "MyJFrog API token that allows you to make changes to your JFrog account. See [Generate a Token in MyJFrog](https://jfrog.com/help/r/jfrog-hosting-models-documentation/generate-a-token-in-myjfrog) for more details. This can also be sourced from the `JFROG_MYJFROG_API_TOKEN` environment variable.",
},
"check_license": schema.BoolAttribute{
Description: "Toggle for pre-flight checking of Artifactory Pro and Enterprise license. Default to `true`.",
Optional: true,
Optional: true,
MarkdownDescription: "Toggle for pre-flight checking of Artifactory Pro and Enterprise license. Default to `true`.",
},
},
}
Expand Down
5 changes: 2 additions & 3 deletions pkg/platform/resource_global_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
"github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/jfrog/terraform-provider-shared/util"
utilfw "github.com/jfrog/terraform-provider-shared/util/fw"
)

Expand Down Expand Up @@ -57,7 +56,7 @@ var globalRoleActions []string = []string{
var _ resource.Resource = (*globalRoleResource)(nil)

type globalRoleResource struct {
ProviderData util.ProvderMetadata
ProviderData PlatformProviderMetadata
}

func NewGlobalRoleResource() resource.Resource {
Expand Down Expand Up @@ -188,7 +187,7 @@ func (r *globalRoleResource) Configure(ctx context.Context, req resource.Configu
if req.ProviderData == nil {
return
}
r.ProviderData = req.ProviderData.(util.ProvderMetadata)
r.ProviderData = req.ProviderData.(PlatformProviderMetadata)
}

func (r *globalRoleResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
Expand Down
5 changes: 2 additions & 3 deletions pkg/platform/resource_license.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/jfrog/terraform-provider-shared/util"
utilfw "github.com/jfrog/terraform-provider-shared/util/fw"
"github.com/samber/lo"
)
Expand All @@ -24,7 +23,7 @@ const (
var _ resource.Resource = (*licenseResource)(nil)

type licenseResource struct {
ProviderData util.ProvderMetadata
ProviderData PlatformProviderMetadata
}

func NewLicenseResource() resource.Resource {
Expand Down Expand Up @@ -105,7 +104,7 @@ func (r *licenseResource) Configure(ctx context.Context, req resource.ConfigureR
if req.ProviderData == nil {
return
}
r.ProviderData = req.ProviderData.(util.ProvderMetadata)
r.ProviderData = req.ProviderData.(PlatformProviderMetadata)
}

func (r *licenseResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
Expand Down
Loading
Loading