Skip to content

Commit

Permalink
introduce posthog
Browse files Browse the repository at this point in the history
  • Loading branch information
zreigz committed Mar 10, 2023
1 parent f83d74f commit c13c3e5
Show file tree
Hide file tree
Showing 11 changed files with 193 additions and 7 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ BUILD ?= $(shell git rev-parse --short HEAD)
DKR_HOST ?= dkr.plural.sh
GOOS ?= darwin
GOARCH ?= amd64
BASE_LDFLAGS ?= -X main.version=$(APP_VSN) -X main.commit=$(BUILD) -X main.date=$(APP_DATE) -X github.com/pluralsh/plural/pkg/scm.GitlabClientSecret=${GITLAB_CLIENT_SECRET} -X github.com/pluralsh/plural/pkg/scm.BitbucketClientSecret=${BITBUCKET_CLIENT_SECRET}
BASE_LDFLAGS ?= -X github.com/pluralsh/plural/pkg/utils.version=$(APP_VSN) -X main.version=$(APP_VSN) -X main.commit=$(BUILD) -X main.date=$(APP_DATE) -X github.com/pluralsh/plural/pkg/scm.GitlabClientSecret=${GITLAB_CLIENT_SECRET} -X github.com/pluralsh/plural/pkg/scm.BitbucketClientSecret=${BITBUCKET_CLIENT_SECRET}
OUTFILE ?= plural.o

help:
Expand Down
4 changes: 2 additions & 2 deletions cmd/plural/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ func TestPluralConfigCommand(t *testing.T) {
{
name: `test "config read" command when config file doesn't exists'`,
args: []string{plural.ApplicationName, "config", "read"},
expectedResponse: "apiVersion: platform.plural.sh/v1alpha1\nkind: Config\nmetadata: null\nspec:\n email: \"\"\n token: \"\"\n namespacePrefix: \"\"\n endpoint: \"\"\n lockProfile: \"\"\n reportErrors: false\n",
expectedResponse: "apiVersion: platform.plural.sh/v1alpha1\nkind: Config\nmetadata: null\nspec:\n email: \"\"\n id: \"\"\n token: \"\"\n namespacePrefix: \"\"\n endpoint: \"\"\n lockProfile: \"\"\n reportErrors: false\n",
},
{
name: `test "config read" command with default test config'`,
args: []string{plural.ApplicationName, "config", "read"},
createConfig: true,
expectedResponse: "apiVersion: platform.plural.sh/v1alpha1\nkind: Config\nmetadata: null\nspec:\n email: [email protected]\n token: abc\n namespacePrefix: test\n endpoint: http://example.com\n lockProfile: abc\n reportErrors: false\n",
expectedResponse: "apiVersion: platform.plural.sh/v1alpha1\nkind: Config\nmetadata: null\nspec:\n email: [email protected]\n id: \"\"\n token: abc\n namespacePrefix: test\n endpoint: http://example.com\n lockProfile: abc\n reportErrors: false\n",
},
}
for _, test := range tests {
Expand Down
27 changes: 24 additions & 3 deletions cmd/plural/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,11 @@ func (p *Plural) deploy(c *cli.Context) error {
if c.Bool("silence") {
continue
}

if man, err := fetchManifest(repo); err == nil && man.Wait {
man, err := fetchManifest(repo)
if err != nil {
return err
}
if man.Wait {
if kubeConf, err := kubernetes.KubeConfig(); err == nil {
fmt.Printf("Waiting for %s to become ready...\n", repo)
if err := application.SilentWait(kubeConf, repo); err != nil {
Expand All @@ -247,7 +250,25 @@ func (p *Plural) deploy(c *cli.Context) error {
fmt.Println("")
}
}

for _, ch := range man.Charts {
utils.PosthogCapture(utils.DeployPosthogEvent, utils.PosthogProperties{
ApplicationName: installation.Repository.Name,
ApplicationID: installation.Id,
PackageType: "helm",
PackageName: ch.Name,
PackageId: ch.Id,
PackageVersion: ch.Version,
})
}
for _, tf := range man.Terraform {
utils.PosthogCapture(utils.DeployPosthogEvent, utils.PosthogProperties{
ApplicationName: installation.Repository.Name,
ApplicationID: installation.Id,
PackageType: "terraform",
PackageName: tf.Name,
PackageId: tf.Id,
})
}
if err := scaffold.Notes(installation); err != nil {
return err
}
Expand Down
14 changes: 13 additions & 1 deletion cmd/plural/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import (
"path/filepath"
"time"

"github.com/pluralsh/plural/pkg/manifest"

"github.com/pkg/browser"
"github.com/urfave/cli"

"github.com/pluralsh/plural/pkg/api"
"github.com/pluralsh/plural/pkg/config"
"github.com/pluralsh/plural/pkg/crypto"
"github.com/pluralsh/plural/pkg/manifest"
"github.com/pluralsh/plural/pkg/provider"
"github.com/pluralsh/plural/pkg/scm"
"github.com/pluralsh/plural/pkg/server"
Expand Down Expand Up @@ -85,6 +86,16 @@ func (p *Plural) handleInit(c *cli.Context) error {
return err
}

project, err := manifest.FetchProject()
if err != nil {
return err
}
project.Owner.ID = me.Id
project.SendMetrics = affirm("Would you be willing to send installation metrics to Plural? We will store data in an aggregated form to analyze the application's deployment", "PLURAL_INIT_AFFIRM_SEND_METRICS")
if err := project.Write(manifest.ProjectManifestPath()); err != nil {
return err
}

utils.Success("Workspace is properly configured!\n")
if gitCreated {
utils.Highlight("Be sure to `cd %s` to use your configured git repo\n", repo)
Expand Down Expand Up @@ -164,6 +175,7 @@ func postLogin(conf *config.Config, client api.Client, c *cli.Context) error {
}

conf.Email = me.Email
conf.ID = me.Id
fmt.Printf("\nlogged in as %s!\n", me.Email)

saEmail := c.String("service-account")
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ require (
github.com/pluralsh/gqlclient v1.3.10
github.com/pluralsh/plural-operator v0.5.3
github.com/pluralsh/polly v0.0.6
github.com/posthog/posthog-go v0.0.0-20221221115252-24dfed35d71a
github.com/rodaine/hclencoder v0.0.1
github.com/samber/lo v1.33.0
github.com/thoas/go-funk v0.9.2
Expand Down Expand Up @@ -104,6 +105,7 @@ require (
github.com/pluralsh/controller-reconcile-helper v0.0.4 // indirect
github.com/stretchr/objx v0.5.0 // indirect
github.com/vektah/gqlparser/v2 v2.5.1 // indirect
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect
github.com/zclconf/go-cty v1.10.0 // indirect
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect
google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44 // indirect
Expand Down
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -909,6 +909,8 @@ github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/posthog/posthog-go v0.0.0-20221221115252-24dfed35d71a h1:Ey0XWvrg6u6hyIn1Kd/jCCmL+bMv9El81tvuGBbxZGg=
github.com/posthog/posthog-go v0.0.0-20221221115252-24dfed35d71a/go.mod h1:oa2sAs9tGai3VldabTV0eWejt/O4/OOD7azP8GaikqU=
github.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1/go.mod h1:nSbFQvMj97ZyhFRSJYtut+msi4sOY6zJDGCdSc+/rZU=
github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY=
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
Expand Down Expand Up @@ -1046,6 +1048,7 @@ github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljT
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.10 h1:p8Fspmz3iTctJstry1PYS3HVdllxnEzTEsgIgtxTrCk=
github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
Expand All @@ -1069,6 +1072,8 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q
github.com/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk=
github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c h1:3lbZUMbMiGUW/LMkfsEABsc5zNT9+b1CvsJx47JzJ8g=
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c/go.mod h1:UrdRz5enIKZ63MEE3IF9l2/ebyx59GyGgPi+tICQdmM=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down
9 changes: 9 additions & 0 deletions pkg/bundle/installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,22 @@ func doInstall(client api.Client, recipe *api.Recipe, repo, name string, refresh
return err
}

posthogProperty := utils.PosthogProperties{
ApplicationName: repo,
RecipeName: recipe.Name,
}
if err := performTests(context, recipe); err != nil {
posthogProperty.Error = fmt.Errorf("failed to perform tests")
utils.PosthogCapture(utils.InstallPosthogEvent, posthogProperty)
return err
}

if err := client.InstallRecipe(recipe.Id); err != nil {
posthogProperty.Error = fmt.Errorf("failed install recipe")
utils.PosthogCapture(utils.InstallPosthogEvent, posthogProperty)
return fmt.Errorf("Install failed, does your plural user have install permissions? error: %w", api.GetErrorResponse(err, "InstallRecipe"))
}
utils.PosthogCapture(utils.InstallPosthogEvent, posthogProperty)

if recipe.OidcSettings == nil {
return nil
Expand Down
1 change: 1 addition & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type Metadata struct {

type Config struct {
Email string `json:"email"`
ID string `yaml:"id" json:"id"`
Token string `yaml:"token" json:"token"`
NamespacePrefix string `yaml:"namespacePrefix"`
Endpoint string `yaml:"endpoint"`
Expand Down
2 changes: 2 additions & 0 deletions pkg/manifest/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type Manifest struct {

type Owner struct {
Email string
ID string
Endpoint string `yaml:"endpoint,omitempty"`
}

Expand All @@ -54,6 +55,7 @@ type ProjectManifest struct {
Project string
Provider string
Region string
SendMetrics bool
Owner *Owner
Network *NetworkConfig
BucketPrefix string `yaml:"bucketPrefix"`
Expand Down
12 changes: 12 additions & 0 deletions pkg/scaffold/scaffold.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"path/filepath"

"github.com/pluralsh/plural/pkg/executor"
"github.com/pluralsh/plural/pkg/utils"
"github.com/pluralsh/plural/pkg/utils/git"
"github.com/pluralsh/plural/pkg/utils/pathing"
"github.com/pluralsh/plural/pkg/wkspace"
Expand Down Expand Up @@ -120,6 +121,17 @@ func (s *Scaffold) Execute(wk *wkspace.Workspace, force bool) error {
preflight.Sha = ""
}

for _, ch := range wk.Charts {
utils.PosthogCapture(utils.BuildPosthogEvent, utils.PosthogProperties{
ApplicationName: wk.Installation.Repository.Name,
ApplicationID: wk.Installation.Id,
PackageType: s.Type,
PackageName: ch.Chart.Name,
PackageId: ch.Chart.Id,
PackageVersion: ch.Version.Version,
})
}

sha, err := preflight.Execute(s.Root, ignore)
if err != nil {
return err
Expand Down
122 changes: 122 additions & 0 deletions pkg/utils/posthog.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package utils

import (
"fmt"
"os"
"path/filepath"

"github.com/pluralsh/plural/pkg/utils/pathing"
"github.com/posthog/posthog-go"
"gopkg.in/yaml.v2"
)

const (
versionPlaceholder = "dev"
)

var (
version = versionPlaceholder
)

type PosthogEvent string

const (
InstallPosthogEvent PosthogEvent = "cli_install"
BuildPosthogEvent PosthogEvent = "cli_build"
DeployPosthogEvent PosthogEvent = "cli_deploy"
)

var posthogClient posthog.Client

type ProjectInfo struct {
Spec *ProjectInfoSpec
}

type ProjectInfoSpec struct {
SendMetrics bool
Cluster string
Provider string
Owner *ProjectInfoOwner
}
type ProjectInfoOwner struct {
ID string
}

type PosthogProperties struct {
ApplicationName string `json:"applicationName,omitempty"`
ApplicationID string `json:"applicationID,omitempty"`
PackageType string `json:"packageType,omitempty"`
PackageName string `json:"packageName,omitempty"`
PackageId string `json:"packageID,omitempty"`
PackageVersion string `json:"packageVersion,omitempty"`
RecipeName string `json:"recipeName,omitempty"`
Error error `json:"error,omitempty"`
}

func newPosthogClient() (posthog.Client, error) {
return posthog.NewWithConfig("phc_r0v4jbKz8Rr27mfqgO15AN5BMuuvnU8hCFedd6zpSDy", posthog.Config{
Endpoint: "https://posthog.plural.sh",
})
}

func posthogCapture(posthogClient posthog.Client, event PosthogEvent, property PosthogProperties) error {
if project, err := getProjectInfo(); err == nil && project.Spec != nil && project.Spec.SendMetrics {
var properties map[string]interface{}
inrec, err := json.Marshal(property)
if err != nil {
return err
}
err = json.Unmarshal(inrec, &properties)
if err != nil {
return err
}
properties["clusterName"] = project.Spec.Cluster
properties["provider"] = project.Spec.Provider
properties["cliVersion"] = version
userID := "cli-user"
if project.Spec.Owner != nil {
userID = project.Spec.Owner.ID
}
LogInfo().Printf("send posthog event %v \n", properties)
return posthogClient.Enqueue(posthog.Capture{
DistinctId: userID,
Event: string(event),
Properties: properties,
})
}
LogInfo().Println("sending events disabled")
return nil
}

func PosthogCapture(event PosthogEvent, property PosthogProperties) {
if posthogClient == nil {
var err error
posthogClient, err = newPosthogClient()
if err != nil {
LogError().Printf("Failed to create posthog client %v", err)
return
}
}
if err := posthogCapture(posthogClient, event, property); err != nil {
LogError().Printf("Failed to send posthog event %v", err)
}
}

func getProjectInfo() (*ProjectInfo, error) {
root, found := ProjectRoot()
if found {
path := pathing.SanitizeFilepath(filepath.Join(root, "workspace.yaml"))
contents, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("could not find workspace.yaml file")
}
var projectInfo ProjectInfo
err = yaml.Unmarshal(contents, &projectInfo)
if err != nil {
return nil, err
}
return &projectInfo, nil
}

return nil, fmt.Errorf("you are not in the project directory")
}

0 comments on commit c13c3e5

Please sign in to comment.