Skip to content

Commit

Permalink
Merge pull request #40 from jfrog/improve-telemetry
Browse files Browse the repository at this point in the history
Improve telemetry
  • Loading branch information
alexhung authored May 4, 2022
2 parents 7b217cb + 385ba8c commit 5a7f38d
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 130 deletions.
2 changes: 1 addition & 1 deletion GNUmakefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
TEST?=./...
TARGET_ARCH?=darwin_amd64
PKG_NAME=pkg/projects
PKG_NAME=pkg/project
PKG_VERSION_PATH=github.com/jfrog/terraform-provider-project/${PKG_NAME}
VERSION := $(shell git tag --sort=-creatordate | head -1 | sed -n 's/v\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1.\2.\3/p')
NEXT_VERSION := $(shell echo ${VERSION}| awk -F '.' '{print $$1 "." $$2 "." $$3 +1 }' )
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ require (
github.com/hashicorp/terraform-plugin-docs v0.7.0
github.com/hashicorp/terraform-plugin-log v0.3.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.14.0
github.com/jfrog/terraform-provider-shared v0.2.0
github.com/jfrog/terraform-provider-shared v0.5.0
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
)

Expand Down
6 changes: 2 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,8 @@ github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH
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/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
github.com/jfrog/terraform-provider-shared v0.1.0 h1:gbhmpOKf3FW5qddhpgDx0hku4H+i/IKH0jnYqLGrmnM=
github.com/jfrog/terraform-provider-shared v0.1.0/go.mod h1:8QRccISRVo/Ht/e7vjcNhjb49BJSheZ1bfEUwGdgZi8=
github.com/jfrog/terraform-provider-shared v0.2.0 h1:7Z6jM12qyM3vU4YfA8tSoHMCnvbvAGeW/w8s6vPFttQ=
github.com/jfrog/terraform-provider-shared v0.2.0/go.mod h1:8QRccISRVo/Ht/e7vjcNhjb49BJSheZ1bfEUwGdgZi8=
github.com/jfrog/terraform-provider-shared v0.5.0 h1:1TEHe3ZkLSNBcxcQ5Ba9X05WiXJpbScRR7eaeXW00CA=
github.com/jfrog/terraform-provider-shared v0.5.0/go.mod h1:2ueIlfizwfDAkL1jm3hmvYBqbMusQtHz33ZpDiPOyxA=
github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE=
github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74=
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
Expand Down
144 changes: 22 additions & 122 deletions pkg/project/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,17 @@ package project
import (
"context"
"fmt"
"net/http"
"net/url"
"regexp"
"time"

"github.com/go-resty/resty/v2"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/jfrog/terraform-provider-shared/client"
"github.com/jfrog/terraform-provider-shared/util"
)

var Version = "0.0.1"
// needs to be exported so make file can update this
var productId = "terraform-provider-project/" + Version

// Provider Projects provider that supports configuration via username+password or a token
// Supported resources are repos, users, groups, replications, and permissions
Expand Down Expand Up @@ -44,151 +43,52 @@ func Provider() *schema.Provider {
},
},

ResourcesMap: map[string]*schema.Resource{
"project": projectResource(),
},
ResourcesMap: util.AddTelemetry(
productId,
map[string]*schema.Resource{
"project": projectResource(),
},
),
}

p.ConfigureContextFunc = func(ctx context.Context, data *schema.ResourceData) (interface{}, diag.Diagnostics) {
terraformVersion := p.TerraformVersion
if terraformVersion == "" {
terraformVersion = "0.13+compatible"
}
configuration, err := providerConfigure(data, terraformVersion)
return configuration, diag.FromErr(err)
return providerConfigure(ctx, data, terraformVersion)
}

return p
}

type ProjectClient struct {
Get func(id string) (Project, error)
}

func buildResty(URL string) (*resty.Client, error) {

u, err := url.ParseRequestURI(URL)
if err != nil {
return nil, err
}

baseUrl := fmt.Sprintf("%s://%s", u.Scheme, u.Host)
restyBase := resty.New().SetHostURL(baseUrl).OnAfterResponse(func(client *resty.Client, response *resty.Response) error {
if response == nil {
return fmt.Errorf("no response found")
}

if response.StatusCode() >= http.StatusBadRequest {
return fmt.Errorf("\n%d %s %s\n%s", response.StatusCode(), response.Request.Method, response.Request.URL, string(response.Body()[:]))
}

return nil
}).
SetHeader("content-type", "application/json").
SetHeader("accept", "*/*").
SetHeader("user-agent", "jfrog/terraform-provider-project:"+Version).
SetRetryCount(20).
SetRetryWaitTime(5 * time.Second).
SetRetryMaxWaitTime(20 * time.Second).
AddRetryCondition(retryOnServiceUnavailable)

restyBase.DisableWarn = true

return restyBase, nil
}

func addAuthToResty(client *resty.Client, accessToken string) (*resty.Client, error) {
if accessToken != "" {
return client.SetAuthToken(accessToken), nil
}
return nil, fmt.Errorf("no authentication details supplied")
}

func checkArtifactoryLicense(client *resty.Client) error {

type License struct {
Type string `json:"type"`
}

type LicensesWrapper struct {
License
Licenses []License `json:"licenses"` // HA licenses returns as an array instead
}

licensesWrapper := LicensesWrapper{}
_, err := client.R().
SetResult(&licensesWrapper).
Get("/artifactory/api/system/license")

if err != nil {
return fmt.Errorf("Failed to check for license. %s", err)
}

var licenseType string
if len(licensesWrapper.Licenses) > 0 {
licenseType = licensesWrapper.Licenses[0].Type
} else {
licenseType = licensesWrapper.Type
}

if matched, _ := regexp.MatchString(`Enterprise`, licenseType); !matched {
return fmt.Errorf("Artifactory Projects requires Enterprise license to work with Terraform!")
}

return nil
}

func providerConfigure(d *schema.ResourceData, terraformVersion string) (interface{}, error) {
func providerConfigure(ctx context.Context, d *schema.ResourceData, terraformVersion string) (interface{}, diag.Diagnostics) {
URL, ok := d.GetOk("url")
if URL == nil || URL == "" || !ok {
return nil, fmt.Errorf("you must supply a URL")
return nil, diag.Errorf("you must supply a URL")
}

restyBase, err := buildResty(URL.(string))
restyBase, err := client.Build(URL.(string), Version)
if err != nil {
return nil, err
return nil, diag.FromErr(err)
}
accessToken := d.Get("access_token").(string)

restyBase, err = addAuthToResty(restyBase, accessToken)
restyBase, err = client.AddAuth(restyBase, "", accessToken)
if err != nil {
return nil, err
return nil, diag.FromErr(err)
}

checkLicense := d.Get("check_license").(bool)
if checkLicense {
err = checkArtifactoryLicense(restyBase)
if err != nil {
return nil, err
licenseErr := util.CheckArtifactoryLicense(restyBase)
if licenseErr != nil {
return nil, licenseErr
}
}

_, err = sendUsageRepo(restyBase, terraformVersion)
if err != nil {
return nil, err
}
featureUsage := fmt.Sprintf("Terraform/%s", terraformVersion)
util.SendUsage(ctx, restyBase, productId, featureUsage)

return restyBase, nil
}

func sendUsageRepo(restyBase *resty.Client, terraformVersion string) (interface{}, error) {
type Feature struct {
FeatureId string `json:"featureId"`
}
type UsageStruct struct {
ProductId string `json:"productId"`
Features []Feature `json:"features"`
}
_, err := restyBase.R().SetBody(UsageStruct{
"terraform-provider-projects/" + Version,
[]Feature{
{FeatureId: "Partner/ACC-007450"},
{FeatureId: "Terraform/" + terraformVersion},
},
}).Post("artifactory/api/system/usage")

if err != nil {
return nil, fmt.Errorf("unable to report usage %s", err)
}
return nil, nil
}
5 changes: 3 additions & 2 deletions pkg/project/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/go-resty/resty/v2"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/jfrog/terraform-provider-shared/client"
)

func TestProvider(t *testing.T) {
Expand All @@ -27,7 +28,7 @@ func getTestResty(t *testing.T) *resty.Client {
t.Fatal("PROJECT_URL or JFROG_URL must be set for acceptance tests")
}
}
restyClient, err := buildResty(projectUrl)
restyClient, err := client.Build(projectUrl, "")
if err != nil {
t.Fatal(err)
}
Expand All @@ -38,7 +39,7 @@ func getTestResty(t *testing.T) *resty.Client {
t.Fatal("PROJECT_ACCESS_TOKEN or JFROG_ACCESS_TOKEN must be set for acceptance tests")
}
}
restyClient, err = addAuthToResty(restyClient, accessToken)
restyClient, err = client.AddAuth(restyClient, "", accessToken)
if err != nil {
t.Fatal(err)
}
Expand Down

0 comments on commit 5a7f38d

Please sign in to comment.