Skip to content

Commit be980e1

Browse files
authored
feat(boostrapper): add installed telemetry request in boostrapper (#184)
1 parent b3d1b18 commit be980e1

File tree

5 files changed

+149
-4
lines changed

5 files changed

+149
-4
lines changed

bootstrapper/cmd/init_org.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/semaphoreio/semaphore/bootstrapper/pkg/installation"
1313
"github.com/semaphoreio/semaphore/bootstrapper/pkg/kubernetes"
1414
"github.com/semaphoreio/semaphore/bootstrapper/pkg/organization"
15+
"github.com/semaphoreio/semaphore/bootstrapper/pkg/telemetry"
1516
"github.com/semaphoreio/semaphore/bootstrapper/pkg/user"
1617
"github.com/semaphoreio/semaphore/bootstrapper/pkg/utils"
1718
log "github.com/sirupsen/logrus"
@@ -52,7 +53,12 @@ var initOrgCmd = &cobra.Command{
5253
}
5354

5455
if os.Getenv("CONFIGURE_INSTALLATION_DEFAULTS") == "true" {
55-
if err := installation.ConfigureInstallationDefaults(instanceConfigClient, orgId); err != nil {
56+
telemetryClient := telemetry.NewTelemetryClient(os.Getenv("CHART_VERSION"))
57+
58+
installationDefaults, err := installation.ConfigureInstallationDefaults(instanceConfigClient, orgId)
59+
if err == nil {
60+
telemetryClient.SendTelemetryInstallationData(installationDefaults)
61+
} else {
5662
log.Errorf("Failed to configure installation defaults: %v", err)
5763
}
5864
}

bootstrapper/helm/templates/init-org-job.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ spec:
8080
value: "true"
8181
- name: TELEMETRY_ENDPOINT
8282
value: {{ .Values.global.telemetry.endpoint }}
83+
- name: CHART_VERSION
84+
value: {{ .Chart.Version }}
8385
- name: KUBE_VERSION
8486
value: {{ .Capabilities.KubeVersion.Version }}
8587
- name: ROOT_USER_SECRET_NAME

bootstrapper/pkg/installation/installation.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,19 @@ import (
1010
log "github.com/sirupsen/logrus"
1111
)
1212

13-
func ConfigureInstallationDefaults(instanceConfigClient *clients.InstanceConfigClient, orgId string) error {
14-
return retry.WithConstantWait("Installation Defaults configuration", 5, 10*time.Second, func() error {
15-
err := instanceConfigClient.ConfigureInstallationDefaults(installationDefaultsParams(orgId))
13+
func ConfigureInstallationDefaults(instanceConfigClient *clients.InstanceConfigClient, orgId string) (map[string]string, error) {
14+
installationDefaults := installationDefaultsParams(orgId)
15+
err := retry.WithConstantWait("Installation Defaults configuration", 5, 10*time.Second, func() error {
16+
err := instanceConfigClient.ConfigureInstallationDefaults(installationDefaults)
1617
if err == nil {
1718
log.Info("Successfully configured Installation Defaults")
1819
return nil
1920
}
2021

2122
return err
2223
})
24+
25+
return installationDefaults, err
2326
}
2427

2528
func installationDefaultsParams(orgId string) map[string]string {
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package telemetry
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"io"
7+
"net/http"
8+
9+
log "github.com/sirupsen/logrus"
10+
)
11+
12+
type RequestPayload struct {
13+
InstallationId string `json:"installation_id"`
14+
KubeVersion string `json:"kube_version"`
15+
Version string `json:"version"`
16+
ProjectsCount int `json:"projects_count"`
17+
OrgMembersCount int `json:"org_members_count"`
18+
State string `json:"state"`
19+
}
20+
21+
type TelemetryClient struct {
22+
chartVersion string
23+
}
24+
25+
func NewTelemetryClient(chartVersion string) *TelemetryClient {
26+
return &TelemetryClient{
27+
chartVersion: chartVersion,
28+
}
29+
}
30+
31+
func (c *TelemetryClient) SendTelemetryInstallationData(installationDefaults map[string]string) {
32+
endpoint := installationDefaults["telemetry_endpoint"]
33+
34+
request := RequestPayload{
35+
InstallationId: installationDefaults["installation_id"],
36+
KubeVersion: installationDefaults["kube_version"],
37+
Version: c.chartVersion,
38+
ProjectsCount: 0,
39+
OrgMembersCount: 1,
40+
State: "installed",
41+
}
42+
43+
jsonData, err := json.Marshal(request)
44+
if err != nil {
45+
log.Errorf("Failed to marshal request payload: %v", err)
46+
return
47+
}
48+
49+
req, err := buildPostRequest(endpoint, bytes.NewBuffer(jsonData))
50+
if err != nil {
51+
log.Errorf("Failed to build request: %v", err)
52+
return
53+
}
54+
55+
resp, err := http.DefaultClient.Do(req)
56+
if err != nil {
57+
log.Errorf("Failed to send request: %v", err)
58+
return
59+
}
60+
defer resp.Body.Close()
61+
62+
if resp.StatusCode < 200 || resp.StatusCode > 299 {
63+
log.Errorf("Failed to send request: %v", resp.Status)
64+
return
65+
}
66+
67+
log.Info("Successfully sent telemetry installation data")
68+
}
69+
70+
func buildPostRequest(uri string, body io.Reader) (*http.Request, error) {
71+
req, err := http.NewRequest(http.MethodPost, uri, body)
72+
if err != nil {
73+
return nil, err
74+
}
75+
76+
req.Header.Set("Content-Type", "application/json")
77+
78+
return req, nil
79+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package telemetry_test
2+
3+
import (
4+
"encoding/json"
5+
"io"
6+
"net/http"
7+
"net/http/httptest"
8+
"testing"
9+
10+
"github.com/google/uuid"
11+
"github.com/semaphoreio/semaphore/bootstrapper/pkg/telemetry"
12+
"github.com/stretchr/testify/assert"
13+
"github.com/stretchr/testify/require"
14+
)
15+
16+
func TestSendTelemetryInstallationData(t *testing.T) {
17+
instId := uuid.New().String()
18+
19+
// Create a mock HTTP server
20+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
21+
22+
require.Equal(t, "POST", r.Method)
23+
require.Equal(t, "application/json", r.Header.Get("Content-Type"))
24+
25+
body, err := io.ReadAll(r.Body)
26+
require.NoError(t, err)
27+
defer r.Body.Close()
28+
29+
var requestPayload telemetry.RequestPayload
30+
err = json.Unmarshal(body, &requestPayload)
31+
require.NoError(t, err)
32+
33+
assert.Equal(t, instId, requestPayload.InstallationId)
34+
assert.Equal(t, "v1.23.0+k3s1", requestPayload.KubeVersion)
35+
assert.Equal(t, "1.0.0", requestPayload.Version)
36+
assert.Equal(t, 0, requestPayload.ProjectsCount)
37+
assert.Equal(t, 1, requestPayload.OrgMembersCount)
38+
assert.Equal(t, "installed", requestPayload.State)
39+
40+
// Respond with HTTP 200 OK
41+
w.WriteHeader(http.StatusOK)
42+
}))
43+
defer server.Close()
44+
45+
// Create telemetry client and test data
46+
client := telemetry.NewTelemetryClient("1.0.0")
47+
installationDefaults := map[string]string{
48+
"telemetry_endpoint": server.URL,
49+
"installation_id": instId,
50+
"kube_version": "v1.23.0+k3s1",
51+
}
52+
53+
// Call function to be tested
54+
client.SendTelemetryInstallationData(installationDefaults)
55+
}

0 commit comments

Comments
 (0)